笔记27 | 通过WindowManager实现悬浮窗口总结

来源:互联网 发布:淘宝促销模板 编辑:程序博客网 时间:2024/05/21 15:41

地址

http://blog.csdn.net/xiangyong_1521/article/details/78401755

目录

  • 关于Window/WindowManagerService的简介

  • ViewManager和WindowManager的实现

  • 举例实现




关于Window/WindowManagerService的简介

  • WindowManagerService


先来看WindowManagerService,从此图可以得知,它是位于Framework层的窗口管理服务,职责就是管理系统中的所有窗口,窗口的本质是什么呢?其实就是一块显示区域,在 Android 中就是绘制的画布:Surface,当一块 Surface 显示在屏幕上时,就是用户所看到的窗口了。WindowManagerService 添加一个窗口的过程,其实就是 WindowManagerService 为其分配一块 Surface 的过程,一块块的 Surface 在 WindowManagerService 的管理下有序的排列在屏幕上

  • Window

Window 是一个抽象类,表示一个窗口,它的具体实现类是 PhoneWindow,实现位于 WindowManagerService 中;Window 有三种类型

  1. 应用 Window:应用类 Window 对应一个 Acitivity;

  2. 子 Window :子 Window 不能单独存在,需要依附在特定的父 Window 中,比如常见的一些 Dialog 就是一个子 Window;

  3. 系统 Window:系统 Window是需要声明权限才能创建的 Window,比如 Toast 和系统状态栏都是系统 Window。

Window 是分层的,每个 Window 都有对应的 z-ordered(处在这些叠加窗口中的位置),层级大的会覆盖在层级小的 Window 上面,这和 HTML 中的 z-index 概念是完全一致的。在三种 Window 中,应用 Window 层级范围是 1~99,子 Window 层级范围是 1000~1999,系统 Window 层级范围是 2000~2999,我们可以用一个表格来直观的表示

Window层级应用1-99子1000-1999系统2000-299这些层级是对应的WindowManager.LayoutParams 的 type 参数,如下图:



ViewManager和WindowManager的实现

  • ViewManager

我们对 Window 的操作是通过 WindowManager 来完成的,WindowManager继承于 ViewManagerWindowManager 是一个接口,它继承自只有三个方法的 ViewManager 接口:

  1. public interface ViewManager

  2. {

  3.    /**

  4.     * 让您添加和删除子视图到活动的接口。得到一个实例

  5.     */

  6.    public void addView(View view, ViewGroup.LayoutParams params);

  7.    public void updateViewLayout(View view, ViewGroup.LayoutParams params);

  8.    public void removeView(View view);

  9. }

三个方法其实就是 WindowManager 对外提供的主要功能,即添加 View、更新 View 和删除 View

  • WindowManager实现 



  1.    public void show(){

  2.        if (mContentView != null) {

  3.            wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

  4.            wmParams.format = PixelFormat.RGBA_8888;

  5.            wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

  6.            wmParams.alpha = 1.0F;

  7.            wmParams.gravity = Gravity.TOP | Gravity.LEFT;

  8.            wmParams.x = 0;

  9.            wmParams.y = 0;

  10.            wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;

  11.            wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

  12.            wm.addView(mContentView, wmParams);

  13.            bShow=true;

  14.        }

  15.    }

  1. 权限:<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>


举例实现

  • service

  1. /*

  2. * ervice中随时监听限制条件的变化以调动悬浮开关

  3. */

  4. private Timer mTimer = null;

  5.    private TimerTask mTimerTask = null;

  6.    private void upTime() {//开启一个线程,在service中随时监听限制条件的变化

  7.        this.mTimerTask=new TimerTask() {

  8.            @Override

  9.            public void run() {

  10.                handler.post(new Runnable() {

  11.                        @Override

  12.                        public void run() {

  13.                            if () {//限制条件

  14.                            MyWindowManager.createwinm(getApplicationContext());//开启窗口

  15.                            }  

  16.                        }

  17.                    });

  18.                }else  

  19.                    if () { //限制条件

  20.                        MyWindowManager.removewinm(getApplicationContext());//关闭窗口

  21.                    }

  22.        };

  23.        this.mTimer.schedule(mTimerTask, 300, 300);

  24.    }

  • WindowManager

  1. /*

  2. * 定义一个实现WindowManager的类,所有需要悬浮的界面可以在此类中定义windowManager

  3. */

  4. public class MyWindowManager {

  5. public static CarDoor carDoor;

  6. public static LayoutParams doorParams;

  7. public static void createwinm(Context context) {

  8.        WindowManager windowManager = getWindowManager(context);

  9.        if (carDoor == null) {

  10.            carDoor = new CarDoor(context);

  11.            if (doorParams == null) {

  12.                doorParams = new LayoutParams();

  13.                doorParams.type = LayoutParams.TYPE_PHONE;

  14.                doorParams.format = PixelFormat.RGBA_8888;

  15.                doorParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL

  16.                        | LayoutParams.FLAG_NOT_FOCUSABLE;

  17.                doorParams.gravity = Gravity.CENTER;

  18.                doorParams.gravity = Gravity.LEFT | Gravity.BOTTOM;

  19.                doorParams.width = carDoor.viewWidth;

  20.                doorParams.height = carDoor.viewHight;

  21.                doorParams.x = 0;

  22.                doorParams.y = 0;

  23.            }

  24.            carDoor.setParams(doorParams);

  25.            windowManager.addView(carDoor, doorParams);

  26.            carDoor.updateViewPosition();

  27.        }

  28.    }

  29.    public static void removewinm(Context context) {

  30.        if (carDoor != null) {

  31.            carDoor.mTimerTask.cancel();

  32.            WindowManager windowManager = getWindowManager(context);

  33.            windowManager.removeView(carDoor);

  34.            carDoor = null;

  35.        }

  36.    }

  37. }

  • CarDoor

  1. /*

  2. * 悬浮界面要要实现什么功能在此类定义就好了;

  3. */

  4. public class CarDoor extends LinearLayout {

  5. public CarDoor(Context context) {

  6.        super(context);

  7.        windowManager=(WindowManager) context.getSystemService(context.WINDOW_SERVICE);

  8.        LayoutInflater.from(context).inflate(R.layout.layout_cardoor,this);

  9.        View view=findViewById(R.id.layout_cardoor1);

  10.        viewWidth=view.getLayoutParams().width;

  11.        viewHight=view.getLayoutParams().height;

  12.        initView(view);

  13.        initData();

  14.        test1();

  15.    }

  16. }


笔记26 | 总结Android的获取系统时间的几种方法

笔记25 | 通过自定义VIEW实现一个圆盘转动UI

笔记24 | 一个中间打开界面的动画

笔记23 | 复习了/而/做......而的几种循环用法

笔记22 |  学习整理开源APP(BaseAnimation)程序源码“中的通讯录效果(三)



结束



阅读全文
0 0
原创粉丝点击