WindowManager的那些蛋疼的事

最近接到一个蛋疼的需求,要在屏幕上显示一个浮动控件。需要能接收点击事件,还要能显示在statusBar(状态栏)之上,不能被状态栏遮住。

于是WindowManager派上作用了。 直接贴代码:

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
            PixelFormat.TRANSLUCENT);

注意,上面的WindowManager.LayoutParams.TYPE_SYSTEM_ERROR这是整个需求的关键,我在这里蛋疼了很久。网上大部分的文章都是用WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAYWindowManager.LayoutParams.TYPE_SYSTEM_ALERT。经过数十次蛋疼的实验失败之后,查看了一下官方文档。

public static final int TYPE_SYSTEM_ALERT

Window type: system window, such as low power alert. These windows are always on top of application windows. In multiuser systems shows only on the owning user's window.

public static final int TYPE_SYSTEM_OVERLAY

Window type: system overlay windows, which need to be displayed on top of everything else. These windows must not take input focus, or they will interfere with the keyguard. In multiuser systems shows only on the owning user's window.

public static final int TYPE_SYSTEM_ERROR

Window type: internal system error windows, appear on top of everything they can. In multiuser systems shows only on the owning user's window.

翻译就免了,看不懂的直接copy然后谷歌翻译。我简要说一下

TYPE_SYSTEM_ALERTTYPE_SYSTEM_OVERLAY的区别,就查了一个statusBar(状态栏),TYPE_SYSTEM_OVERLAY的可以覆盖在状态栏之上,而TYPE_SYSTEM_ALERT不行。但是TYPE_SYSTEM_OVERLAY添加的view是不能获取焦点的,别跟我说什么FLAG_NOT_FOCUSABLE,FLAG_NOT_TOUCH_MODAL啥的,都没用。也就是说我的需求无法满足。在我临近放弃的时候,发现还有一个TYPE_SYSTEM_ERROR。仔细一看说明,卧槽,这不是跟TYPE_SYSTEM_OVERLAY一样牛逼么(which need to be displayed on top of everything else)?而且还没有任何附加条件(比如:These windows must not take input focus)。

于是,于是我完成了我的需求。

小球球

继续阅读此作者的更多文章

深圳