Android O后不使用TYPE_SYSTEM_OVERLAY如何实现Muviz Edge式状态栏边缘覆盖层
Android 8.0+ 实现状态栏层级悬浮绘制(类Muviz Edge效果)方案
Muviz Edge 没有使用已废弃的 TYPE_SYSTEM_OVERLAY,核心是基于 Android O 官方推荐的悬浮窗类型配合窗口参数调整实现效果,具体实现逻辑如下:
- 首先完成权限配置
Android 6.0 及以上版本需要先申请SYSTEM_ALERT_WINDOW权限,在AndroidManifest中声明权限后,引导用户跳转至系统设置页开启「显示在其他应用上层」权限,这是所有上层悬浮窗的必备前提。 - 配置 WindowManager 布局参数
窗口类型指定为WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,该类型是Android O之后官方替代TYPE_SYSTEM_OVERLAY的合法悬浮窗类型,层级优先级足够覆盖系统状态栏区域。
同时添加以下Flags配置:
宽高均设置为int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN // 允许窗口延伸到整个屏幕区域,包含状态栏 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS // 取消系统对窗口的布局边界限制,允许绘制到系统装饰View区域 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 不抢夺输入焦点,不影响用户操作其他应用WindowManager.LayoutParams.MATCH_PARENT,让悬浮窗占满整个屏幕空间。 - 调整布局适配逻辑
你当前实现的内容显示在状态栏后方,大概率是根布局设置了android:fitsSystemWindows="true",系统会自动给布局添加和状态栏等高的top padding,将内容挤到状态栏下方,或是未添加上述的FLAG_LAYOUT_NO_LIMITS配置,系统默认禁止内容绘制到状态栏区域。
如需绘制在状态栏上方:给根布局设置android:fitsSystemWindows="false",布局内的内容即可覆盖状态栏区域显示。
如需绘制在状态栏下方:可保留fitsSystemWindows="true"配置,或是动态获取状态栏高度后手动给根布局添加对应top padding即可。 - 动态获取状态栏高度做精准适配
可以通过以下代码获取不同机型的状态栏高度,实现绘制区域的精准控制:fun getStatusBarHeight(context: Context): Int { var height = 0 val resId = context.resources.getIdentifier("status_bar_height", "dimen", "android") if (resId > 0) { height = context.resources.getDimensionPixelSize(resId) } return height }
注意:小米、华为等国产ROM对悬浮窗做了额外权限限制,部分机型需要额外开启「后台弹出界面」权限才能保证应用在后台时悬浮窗正常显示。
内容的提问来源于stack exchange,提问作者Wai Yan
相关产品推荐
相关产品推荐

