通过WindowManager创建窗口

概要

窗口(Window)的概念平时并不是很常用,但有时候我们需要创建一个悬浮窗,这时候就需要使用Window来实现,通过WindowManager来添加一个Window,Window是一个抽象的概念,以View的形式存在。

WindowManager类

WindowManager正如其名,是外界访问Window的入口。WindowManager提供了三个方法。

addView()方法

public void addView(View view, ViewGroup.LayoutParams params)
添加view到窗口
- view:需要添加到窗口的view
- params:用于配置创建的窗口信息

    //在安卓6.0及以后需要判断是否具有权限(是否允许应用出现在其他应用之上)
    if (Build.VERSION.SDK_INT >= 23) {
        //如果已勾选“出现在其他应用之上”
        if (Settings.canDrawOverlays(MainActivity.this)) {
            showFloatView();
        } else {
        //否则进入打开权限界面有用户手动授权
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            startActivity(intent);
        }
    } else {
        showFloatView();
    }

    void showFloatView(){
        //这里以创建一个悬浮的ImageView为例
        ImageView floatView = new ImageView(this);
        floatView.setImageResource(R.drawable.img_1);

        //创建一个WindowManager对象
        WindowManager windowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);

        //使用LayoutParams配置窗口信息,这里直接在构造方法中设置,也可以创建后设置
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,  //设置窗口大小,此处为包裹内容
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,  //悬浮在所有窗口之上
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,   //不获取焦点
                PixelFormat.TRANSLUCENT);    //透明?

        params.gravity = Gravity.TOP | Gravity.LEFT;    //设置窗口对齐方式
        params.x = 0;
        params.y = 100;

        windowManager.addView(floatView, params);    //显示窗口,对应为removeView()     
    }

removeView()方法

public void removeView(View view)
从窗口移除view

updateViewLayout()方法

public void updateViewLayout(View view, ViewGroup.LayoutParams params)
更新view的显示。

通常需要监听view的触摸事件,获取坐标等数据,然后在params变量中重新填充数据,调用此方法更新即可。

ViewGroup.LayoutParams类

  • 常用flag
    • FLAG_NOT_FOCUSALBE:不获取焦点,同时会启用FLAG_NOT_TOUCH_MODAL。
    • FLAG_NOT_TOUCH_MODAL:开启后系统会将window区域之外的点击事件传递给底层的window,区域之内由自己处理,一般需要开启,否则无法响应单击事件。
    • FLAG_SHOW_WHEN_LOCKED:让window显示在锁屏界面上。
  • x、y:窗口显示的位置
  • width、height:窗口的宽高
  • gravity:窗口显示的对齐方式
  • type:窗口类型
  • format:The desired bitmap format. May be one of the constants in PixelFormat. Default is OPAQUE.(不是很理解,暂时把原话搬过来)

你可能感兴趣的:(android学习)