Android-WindowManager

来源:互联网 发布:网络科学引论 编辑:程序博客网 时间:2024/05/29 21:30

       经常在博客上看到很多同龄的大神,总会感叹为何别人的世界为什么这么大?

       有时候鼓励自己,即使自己弱,也要坚持写博客,无论自己水平如何,自我安慰吧哈哈

        

        

之前做锁屏的时候,使用到了悬浮窗,悬浮窗通过WindowManager来实现,为了更多了解这个东西,可是找尽了好多资料,翻阅了很多网站,接下来做个学习笔记吧。


Google对WindowManager的介绍:

WindowManager

implements ViewManager
android.view.WindowManager

Class Overview


The interface that apps use to talk to the window manager.

Use Context.getSystemService(Context.WINDOW_SERVICE) to get one of these.

Each window manager instance is bound to a particular Display. To obtain a WindowManager for a different display, usecreateDisplayContext(Display) to obtain a Context for that display, then use Context.getSystemService(Context.WINDOW_SERVICE) to get the WindowManager.

The simplest way to show a window on another display is to create a Presentation. The presentation will automatically obtain a WindowManager andContext for that display.

See also:

  • getSystemService(Class)
  • WINDOW_SERVICE



Window和WindowManager

(1)Window是抽象类,具体实现是PhoneWindow,通过WindowManager就可以创建Window。WindowManager是外界访问Window的入口,但是Window的具体实现是在WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC过程。所有的视图例如Activity、Dialog、Toast都是附加在Window上的。

 

(2)window共有三种类型:应用window,子window和系统window。应用window对应着一个Activity,子window不能独立存在,需要附属在特定的父window之上,比如Dialog就是子window。系统window是需要声明权限才能创建的window,比如Toast和系统状态栏这些都是系统window,需要声明的权限是<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />。

 

(3)window是分层的,每个window都对应着z-ordered,层级大的会覆盖在层级小的上面,应用window的层级范围是1~99,子window的层级范围是1000~1999,系统window的层级范围是2000~2999。


WindowManager : How to use?

(1)初始化

   WindowManager mWindowManager =     (WindowManager)getSystemService(Context.WINDOW_SERVICE);

(2)addView

WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); 

mWindowManager .addView(mView,mParams);

(3)removeView

if(mView.isAttachToWindow())

     mWindowManager .removeView(mView);

// or use  removeViewImmediate(View view) 



WindowManager 实现悬浮窗

两个关键参数:type 和 flag

TYPE

这里列举我实现过的几种:

     信息窗口。用于显示toast。(使用这个type不需要申请悬浮窗权限)

     public static final int TYPE_TOAST            = FIRST_SYSTEM_WINDOW +5;

 

     电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。

     public static final int TYPE_PHONE            = FIRST_SYSTEM_WINDOW+2;

 

     系统提示。它总是出现在应用程序窗口之上。(无法覆盖状态栏和密码锁)

     public static final int TYPE_SYSTEM_ALERT      =  FIRST_SYSTEM_WINDOW +3;

 

     锁屏窗口。(开发者无法使用这个type,系统设置了它为removed)

     public static final int TYPE_KEYGUARD          = FIRST_SYSTEM_WINDOW +4;

 

     系统内部错误提示,显示于所有内容之上。(包括覆盖状态栏和密码锁)

     public static final int TYPE_SYSTEM_ERROR      =  FIRST_SYSTEM_WINDOW +10;


FLAG:

      窗口之后的内容变暗。

      public static final int FLAG_DIM_BEHIND       = 0x00000002;

      窗口之后的内容变模糊。

      public static final int FLAG_BLUR_BEHIND       = 0x00000004; 

      不许获得焦点。

      不能获得按键输入焦点,所以不能向它发送按键或按钮事件。那些事件将发送给它后面的可以获得焦点的窗口。此选项还会设置 FLAG_NOT_TOUCH_MODAL选项。设置此选项,意味着窗口不能与软输入法进行交互(换句话说,它可以 全屏显示,如果需要的话,可覆盖输入法窗口)。要修改这一行为,可参考FLAG_ALT_FOCUSALBE_IM选项。

      public static final int FLAG_NOT_FOCUSABLE     = 0x00000008;

 

      不接受触摸屏事件。

      public static final int FLAG_NOT_TOUCHABLE     = 0x00000010;

 

      当窗口可以获得焦点(没有设置 FLAG_NOT_FOCUSALBE 选项)时,仍然将窗口范围之外的点设备事件(鼠标、触摸屏)发送给后面的窗口处理。否则它将独占所有的点设备事件,而不管它们是不是发生在窗口范围内。

      public static final int FLAG_NOT_TOUCH_MODAL   = 0x00000020;

 

      如果设置了这个标志,当设备休眠时,点击触摸屏,设备将收到这个第一触摸事件。

      通常第一触摸事件被系统所消耗,用户不会看到他们点击屏幕有什么反应。

      public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;

 

      当此窗口为用户可见时,保持设备常开,并保持亮度不变。

      public static final int FLAG_KEEP_SCREEN_ON    = 0x00000080;

 

      窗口占满整个屏幕,忽略周围的装饰边框(例如状态栏)。此窗口需考虑到装饰边框的内容。

      public static final int FLAG_LAYOUT_IN_SCREEN   =0x00000100;

 

      允许窗口扩展到屏幕之外。

      public static final int FLAG_LAYOUT_NO_LIMITS   =0x00000200;

 

      窗口显示时,隐藏所有的屏幕装饰(例如状态条)。使窗口占用整个显示区域。

      public static final int FLAG_FULLSCREEN     = 0x00000400;

 

      此选项将覆盖FLAG_FULLSCREEN选项,并强制屏幕装饰(如状态条)弹出。

      public static final int FLAG_FORCE_NOT_FULLSCREEN   =0x00000800;

 

      抖动。指 对半透明的显示方法。又称“点透”。图形处理较差的设备往往用“点透”替代Alpha混合。

      public static final int FLAG_DITHER           = 0x00001000;

 

      不允许屏幕截图。

      public static final int FLAG_SECURE           = 0x00002000;

 

      一种特殊模式,布局参数用于指示显示比例。

      public static final int FLAG_SCALED           = 0x00004000;

 

      当屏幕有可能贴着脸时,这一选项可防止面颊对屏幕造成误操作。

      public static final int FLAG_IGNORE_CHEEK_PRESSES   = 0x00008000;

 

      当请求布局时,你的窗口可能出现在状态栏的上面或下面,从而造成遮挡。当设置这一选项后,窗口管理器将确保窗口内容不会被装饰条(状态栏)盖住。

      public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;

 

      反转FLAG_NOT_FOCUSABLE选项。

      如果同时设置了FLAG_NOT_FOCUSABLE选项和本选项,窗口将能够与输入法交互,允许输入法窗口覆盖;

      如果FLAG_NOT_FOCUSABLE没有设置而设置了本选项,窗口不能与输入法交互,可以覆盖输入法窗口。

      public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;

 

      解除锁屏。只有锁屏界面不是加密的才能解锁。如果锁屏界面是加密的,那么用户解锁之后才能看到此窗口,除非设置了FLAG_SHOW_WHEN_LOCKED选项。

      public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;

 

      锁屏界面淡出时,继续运行它的动画。

      public static final int FLAG_KEEP_SURFACE_WHILE_ANIMATING =0x10000000;

 

      以原始尺寸显示窗口。用于在兼容模式下运行程序。

      public static final int FLAG_COMPATIBLE_WINDOW = 0x20000000;

 

      用于系统对话框。设置此选项的窗口将无条件获得焦点。

      public static final int FLAG_SYSTEM_ERROR = 0x40000000;


       悬浮窗实例:

        WindowManager.LayoutParams rootViewParams;        rootViewParams.format = PixelFormat.RGBA_8888; // 设置透明背景        rootViewParams.type = WindowManager.LayoutParams.TYPE_SYETEM_ALERT;        rootViewParams.width = WindowManager.LayoutParams.MATCH_PARENT;        rootViewParams.height = WindowManager.LayoutParams.MATCH_PARTENT;        rootViewParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL                       | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        windowManager.addView(mView, rootViewParams);

     
       如上就实现一个全屏显示的悬浮窗属性为TYPE_SYSTEM_ALERT,即系统提示,可以覆盖所有的应用窗口,但是会被系统锁屏和下拉状态栏覆盖。

    

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子五年级学习成绩差该怎么办 孩子临近中考学习成绩很差该怎么办 初中生成绩不好家长该怎么办 成绩差该怎么办贴吧 宝宝只会匍匐爬怎么办 一年级的孩子数学不好怎么办 小学一年级孩子数学不好怎么办 孩子上一年级数学太差怎么办 智商低情商也低怎么办? 孩子字写得很大怎么办 孩子拿笔重 写字太黑 怎么办 孩子语文成绩好数学不行怎么办? 孩子现在二年级特别叛逆怎么办 孩子又笨又蠢怎么办 四年级孩子数学计算能力差怎么办 孩子四年级数学理解能力差怎么办 孩子小学四年级数学很差怎么办 孩子做作业太慢怎么办 小学三年级数学成绩差怎么办 初一数学考了3分怎么办 初二物理太差该怎么办 三年级孩子字写的差怎么办 小学三年级数学才考86怎么办 小孩子一发脾气就打妈妈怎么办 孩子做错事不肯道歉怎么办 小孩写作业注意力不集中怎么办 六年级的数学下册差怎么办 一年级小孩做作业慢怎么办 静不下心写作业怎么办 二年级应用题太差怎么办 小学二年级数学差怎么办 小学二年级成绩差怎么办 6个月小孩爱动怎么办 儿子叛逆期我该怎么办 宝宝两岁好动不听话怎么办 生宝宝后奶水少怎么办 生了孩子没出来怎么办 孩子在学校表现不好怎么办 3岁半宝宝话太多怎么办 孩子不喜欢和小朋友玩怎么办 孩子不喜欢和小朋友说话怎么办