使用WindowManager实现Android悬浮窗
ShaRoyer
8年前
<p>在做项目的时候有时候会用到windowmanager,下面将一些核心代码贴出来供参考。</p> <p>效果图</p> <p><img src="https://simg.open-open.com/show/c5e02d12d6e8f03769212e4934434e56.png"></p> <p style="text-align:center">windowmanager.png</p> <p>声明权限</p> <pre> <code class="language-java"><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /></code></pre> <p>控制类</p> <pre> <code class="language-java">package com.test.window; import java.lang.reflect.Method; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; public class ControlService extends Service { public static final String TAG = ControlService.class.getSimpleName(); LayoutInflater mLayoutInflater; public static Context mContext; Test testView; Test2 testView2; public static int screenWidth = 0, screenHeight = 0; public static WindowManager mWindowManager; public static Window mWindow; static ColorDrawable colorDrawable = new ColorDrawable(); public static final int CHANGE_VIEW_EVENT = 0X30;// 界面转换事件标志 public static final int LIVE_TV = 0x39;// 主界面 public static final int TEST_VIEW = 13;// 第一个界面 public static final int TEST_VIEW2 = 14;// 第二个界面 public static Handler myHandler; class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case CHANGE_VIEW_EVENT: changeView(msg); break; } } } public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { String event = intent.getStringExtra(Const.START_SERVICE_HEAD); if (event == null) { return super.onStartCommand(intent, flags, startId); } else if (Const.START_DTV_EVENT.equals(event)) { changeViewEvent(LIVE_TV, TEST_VIEW, null); } } return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); myHandler = new MyHandler(); mContext = this; mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metric = new DisplayMetrics(); mWindowManager.getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 屏幕宽度(像素) int height = metric.heightPixels; // 屏幕高度(像素) screenHeight = height; screenWidth = width; String POLICYMANAGER_CLASS_NAME = "com.android.internal.policy.PolicyManager"; try { Class policyManagerClass = Class.forName(POLICYMANAGER_CLASS_NAME); Class[] parameterTypes = { Context.class }; Method method = policyManagerClass.getMethod("makeNewWindow", parameterTypes); mWindow = (Window) method.invoke(null, mContext); mWindow.setFormat(PixelFormat.TRANSLUCENT); mWindow.requestFeature(Window.FEATURE_NO_TITLE); mWindow.setWindowManager(mWindowManager, null, null); colorDrawable.setAlpha(0); } catch (Exception e1) { e1.printStackTrace(); } testView = new Test(mLayoutInflater, mContext); testView2 = new Test2(mLayoutInflater, mContext); } private void changeView(Message msg) { int toView = msg.arg2; switch (toView) { case TEST_VIEW: testView.showView(); break; case TEST_VIEW2: testView2.showView(); break; case LIVE_TV: removeContentView(); break; } } public static void changeViewEvent(int ar1, int ar2, Object obj) { Message msg = myHandler.obtainMessage(CHANGE_VIEW_EVENT, ar1, ar2, obj); myHandler.sendMessage(msg); } static Handler handler = new Handler(); public static void setContentView(View view, LayoutParams params) { try { mWindowManager.removeView(mWindow.getDecorView()); } catch (Exception e) { e.printStackTrace(); } mWindow.setBackgroundDrawable(colorDrawable); mWindow.setContentView(view, params); mWindowManager.addView(mWindow.getDecorView(), params); } public static void removeContentView() { try { mWindowManager.removeView(mWindow.getDecorView()); } catch (Exception e) { e.printStackTrace(); } } @Override public IBinder onBind(Intent intent) { return null; } }</code></pre> <p>界面展示</p> <pre> <code class="language-java">package com.test.window; import com.htv.daoshi.R; import android.content.Context; import android.graphics.PixelFormat; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.Button; /** * Created by Think on 2016/9/19. */ public class Test implements View.OnKeyListener, View.OnClickListener { public static final String TAG = Test.class.getSimpleName(); Context context; View myRoot; Button btnSkip,btnClose; WindowManager.LayoutParams mParams; int x, y, width, height; public Test(LayoutInflater inflater, Context c) { context = c; width = ControlService.screenWidth; height = ControlService.screenHeight * 264 / 720; x = 0; y = 0; mParams = new WindowManager.LayoutParams(); mParams.width = width; mParams.height = height; mParams.x = x; mParams.y = y; mParams.gravity = Gravity.RIGHT | Gravity.BOTTOM; mParams.format = PixelFormat.TRANSLUCENT; mParams.type = WindowManager.LayoutParams.TYPE_PHONE; myRoot = (View) inflater.inflate(R.layout.test, null); btnSkip = (Button) myRoot.findViewById(R.id.btn_skip); btnClose = (Button) myRoot.findViewById(R.id.btn_close); btnSkip.setOnClickListener(this); btnSkip.setOnKeyListener(this); btnClose.setOnClickListener(this); btnClose.setOnKeyListener(this); } /** * 显示view */ public void showView() { ControlService.setContentView(myRoot, mParams); } /** * 关闭view */ public void closeView() { ControlService.removeContentView(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_skip://跳转到第二个windowmanager ControlService.changeViewEvent(ControlService.TEST_VIEW, ControlService.TEST_VIEW2, null); break; case R.id.btn_close://关闭 closeView(); break; } } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { closeView(); return true; } return false; } }</code></pre> <p> </p> <p> </p> <p>来自:http://www.jianshu.com/p/29b385e53feb</p> <p> </p>