Window和WindowManager

  • 在Android系统中,Window有三种类型,分别是应用 window、子window、系统window。WindowManager与WindowManagerService的交互是一个IPC过程。

  • WindowManager常用的只有三个方法,即添加View、更新View和删除View,这三个方法定义在ViewManager中,而WindowManager继承了ViewManager 。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.TYPE_APPLICATION,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT
    );
    View view = new View(this);
    windowManager.addView(view, params);

  • 常见flags:

    FLAG_NOT_FOCUSABLE:不需要获取焦点,不接受各种输入事件(同时启用FLAG_NOT_TOUCH_MODAL)。最终事件传给下层具有焦点的Window

    FLAG_NOT_TOUCH_MADAL:系统将当前Window区域以外的单击事件传给下一层Window,当前Window区域内的单击事件则自己处理。

    FLAG_SHOW_WHEN_LOCKED:让Window显示在锁屏界面上

  • 常见Type:

    应用类Window:对应着一个Activity

    子Window:无法单独存在,需要附属在特定的父Window上(比如:Dialog就是子Window)。

    系统Window:需要声明权限在创建(Toast,系统状态栏都是)

  • Window的分层概念:

    Window是分层的,层级大的会覆盖在层级小的Window上面,应用Window层级范围是199,子Window10001999,系统Window2000~2999(同时系统层级有许多值,一般采用TYPE_SYSTEM_OVERLAY,并声明权限)

  • 拖动Window效果实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public void onTouch(View v,MontionEvent event){
    //获取当前绝对位置
    int rawX= (int)event.getRawX();
    int rawY = (int)event.getRawY();
    //当移动的时候,将位置给Layout,然后从新载入layotu
    switch(event.geAction){
    case MotionEvent.ACTION_MOVE:
    mLayoutParams.x = rawX;
    mLayoutParans.y = rawY;
    mWindowManger.updateViewLayout(view,mLayoutParams);
    break;
    }
    }
  • WindowManager方法实现

    1
    2
    3
    4
    5
    6
    7
    8
    public interface ViewManager{
    //添加View
    public void addView(View view,ViewGroup.LayoutParams params);
    //升级View的Layout
    public void updateViewLayout(View view,ViewGroup.LayoutParams params);
    //移除View
    public void removeView(View view);
    }