WindowManager详解

简介

Window是一个抽先类,代表一个窗口,具体实现类是PhoneWindow,Android中所有的View的展示都是依赖于Window的,Window是View的管理者,事件分发也是由window传递给DecorView,在由DecorView分发给子View。可以通过WindowManager来获取一个Window,WindowManager是访问Window的入口。

添加Window

1
2
3
4
5
6
7
8
9
10
11
12
View view = LayoutInflater.from(this).inflate(R.layout.layout_window, null);
mLayoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, 0, 0,
PixelFormat.TRANSPARENT);//0,0 分别是type和flags参数,在后面分别配置了
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLayoutParams.x = 0;
mLayoutParams.y = 0;
mWindowManager.addView(view, mLayoutParams);

Window Type

Type包含三种类型,application_window、sub_window、system_window,每种类型都包含自己的子类型,每个类型都有自己的层级范围,层级高的会覆盖在层级低的上面。

  1. application_window:应用级别窗口,对应层级1-99,对应着一个Activity,在离开页面的时候需要销毁
  2. sub_window:对应层级1000-1999,子窗口是指该窗口必须要有一个父窗口,这个窗口可以是应用级别的PopupWindow、Dialog就是一个子窗口,Dialog不能用application context的原因就是这。
  3. system_window:对应层级2000-2999,系统级别窗口不需要对应的Activity有,也不需要父窗口,展示范围是整个手机,需要申请权限
1
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Window Flag

  • FLAG_NOT_FOCUSABLE:表示window不需要获取焦点,也不需要接收各种输入事件。此标记会同时启用FLAG_NOT_TOUCH_MODAL,最终事件会直接传递给下层的具有焦点的window;
  • FLAG_NOT_TOUCH_MODAL:在此模式下,系统会将window区域外的单击事件传递给底层的window,当前window区域内的单击事件则自己处理,一般都需要开启这个标记;
  • FLAG_SHOW_WHEN_LOCKED:开启此模式可以让Window显示在锁屏的界面上。

Window的使用

WindowManager是Window的唯一操作入口,它实现了ViewManager,只有三个方法addView(),updateViewLayout(),removeView(),我们可以通过这三个方法来对Window进行操作
但WindowManager也是一个interface,具体实现类是WindowManagerImpl,通过源码可以看到,WindowManager的add、remove、update操作都交由WindowManagerGlobal来做,它是一个单例,所以我们就知道了所有Window的管理其实都是有WindowManagerGlobal来做的,具体如下图。

https://user-gold-cdn.xitu.io/2016/11/29/de065f5755c0e4931bc2668166116cd5,