Window和WindowManage

Window表示是一个窗口的概念,它是一个抽象类,具体的实现是PhoneWindow,创建一个Window是很简单的事,只需要通过WindowManager就可以完成,Android中所有的视图都是通过Window来实现的,比如Activity,Toast和Dialog,当我们需要做悬浮窗口的需求的时候,就需要用到它们,下面来看看


Window和WindowManager

先来看看如何通过WindowManager添加一个Window

        Button button=new Button(this);
        WindowManager wmManager=(WindowManager) getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams lp=new WindowManager.LayoutParams();
        lp.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
        lp.gravity= Gravity.TOP;
        lp.x=100;
        lp.y=300;
        wmManager.addView(button,lp);

代码很简单,创建一个view之后就可以用WindowManager的addView方法引用到屏幕x=100和y=300坐标上了,其实WindowManager常用的方法就是添加view,更新view和删除view,也就是addView,updateViewLayout和removeView

(一)Flags

参数表示Window的属性,它有很多选项,通过这些选项可以控制Window的显示特性

FLAG_NOT_FOCUSABLE

表示window不需要获取焦点,这个比较好理解,设置了这个属性后,window将不会获取到焦点

FLAG_NOT_TOUCH_MODAL

在此模式下,系统会将当前Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则自己处理。 一般来说都需要开启此标记,否则其他Window将无法收到单击事件

FLAG_SHOW_WHEN_LOCKED

此模式可以让Window显示在锁屏的界面上


(二)Type

Type代表的是window的类型,共有3种,分别是:应用window,子window和系统window,应用window对应一个Activity,子window需要依附在父window上,不能单独存在,比如dialog,系统window就是系统提供的,比如toast,状态栏等,这些在使用的时候需要声明权限,否则报错,每一类型的window都有一个范围

 
应用window(1-99):Activity,Fragment等
子window(1000-1999):Dialog,Popupwindow等
系统window(2000-2999):Toast,状态栏,通知等

层级范围对应这WindowManager.LayoutParams的type参数,层级大的会覆盖在层级小的Window上面。所以系统层级是最大的,系统层级一般选用TYPE_SYSTEM_ERROR或者TYPE_SYSTEM_OVERLAY


上面提到了windowManger对view的操作有addView,updateViewLayout和removeView,这3个方法定义在ViewManager中,而WindowManger是继承了ViewManager,我们来看看这三个方法:

public interface ViewManager  
{  
    /** 
     * Assign the passed LayoutParams to the passed View and add the view to the window. 
     * 

Throws {@link android.view.WindowManager.BadTokenException} for certain programming * errors, such as adding a second view to a window without removing the first view. *

Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a * secondary {@link Display} and the specified display can't be found * (see {@link android.app.Presentation}). * @param view The view to be added to this window. * @param params The LayoutParams to assign to view. */ public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); }

这3个功能足够我们平常用了,其实WindowManager操作Window的过程就好像Window操作view的过程,我们有时候看到那些可以拖动Window的效果,其实就可以通过updateViewLayout来实现,设置view的onTouchListener,然后根据手指拖动来改变x和y的值,不断更新view就可以了

 button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int x = (int) event.getRawX();
                int y= (int) event.getRawY();
                switch (event.getAction()){
                    case MotionEvent.ACTION_MOVE:
                        lp.x=x;
                        lp.y=y;
                        wmManager.updateViewLayout(button,lp);
                        break;
                }
                return false;
            }
        });

好了,这篇文章到这就结束了

你可能感兴趣的:(Window和WindowManage)