理解Window和WindowManager(一)

2018-09-16  本文已影响0人  阿泽Leo

Window和WindowManager

Window是个窗口的概念,如果我们需要实现一个类似悬浮窗的东西,那么就需要用到Window。

Window是一个抽象类,实现类是PhoneWindow。WindowManager是外界访问Window的入口,Window的具体实现位于WindowManagerService中。Window实际是Android中View的直接管理者。

通过代码演示如果添加Window:

    @SuppressLint("ClickableViewAccessibility")
    private void addViewToWindow() {
        final Button button = new Button(this);
        button.setText("button");
        mParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT);
        mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
        mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
        mParams.gravity = Gravity.LEFT | Gravity.TOP;
        mParams.x = 100;
        mParams.y = 300;
        getWindowManager().addView(button, mParams);
    }

这段代码可以将一个button添加到屏幕中(100,300)的位置。这其中的flags和type参数比较重要。
Flags

  1. FLAG_NOT_FOCUSABLE
    表示Window不需要获取焦点,会同时启用FLAG_NOT_TOUCH_MODAL。
  2. FLAG_NOT_TOUCH_MODAL
    系统会将当前Window区域以外的单击事件传递给底层的Window,当前Window区域内的单击事件自己处理。一般来说都需要开启此标记。
  3. FLAG_SHOW_WHEN_LOCKED
    开启此模式可以让WIndow显示在锁屏的界面上。

Type
表示Window的类型,有应用Window,子Window,系统Window。

  1. 应用类Window对应着一个Activity。
  2. 子Window不能单独存在,只能附属在特定的父Window中,比如Dialog。
  3. 系统Window需要声明权限才能创建,比如Toast和系统状态栏。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Window是分层的,每个Window都有对应的z-order,层级大的会覆盖在层级小的Window上面。应用类Window层级范围是1-99,子Window层级范围是1000-1999,系统Window层级是2000-2999,这些范围对应着WindowManager.LayoutParams的type参数。
WindowManager常用的方法有三个,添加View,更新View,删除View。这三个方法定义在ViewManager中,WindowManager继承了ViewManager。

Window类型 层级
应用Window 1-99
子Window 1000-1999
系统Window 2000-2999
public interface ViewManager
{
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}
上一篇下一篇

猜你喜欢

热点阅读