首先我们来了解一下几个设置沉浸式状态栏的基础属性:
1.View.SYSTEM_UI_FLAG_LOW_PROFILE:低调模式, 会隐藏不重要的状态栏图标;
2.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏导航栏;
3.View.SYSTEM_UI_FLAG_FULLSCREEN:状态栏隐藏(高度不变);
4.View.SYSTEM_UI_FLAG_LAYOUT_STABLE:保持整个View稳定, 常和控制System UI悬浮, 隐藏的Flags共用, 使View不会因为System UI的变化而重新layout;
5.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:视图延伸至导航栏区域,导航栏覆盖在视图之上(在style中设置windowTranslucentNavigation);
6.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN :视图延伸至状态栏区域,状态栏覆盖在视图之上(在style中设置windowTranslucentStatus);
7.View.SYSTEM_UI_FLAG_IMMERSIVE:配合2或3同时使用,假设同时设置了2和7,状态栏隐藏,此时在状态栏顶部下滑,系统清除之前的“2”设置,重新唤出状态栏,导航栏同理,滑动方向为由下至上;
8.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY:作用与7相似,但是设置并未被清除,所以状态栏与导航栏
在被唤出3s后或再次点击时,再次隐藏。
沉浸式状态栏设置现在普遍应用的有以下几种方法:
1,对外层布局设置android:fitsSystemWindows="true"的同时,修改状态栏背景色;
2,根布局里添加占位状态栏,并设置状态栏透明;
3,通过调用setSystemUiVisibility(int visibility),设置上边提到的FLAG(SYSTEM_UI_FLAG_FULLSCREEN)。
在一些特殊页面,比如开屏图这种需要整张图片,并隐藏状态栏的时候,就需要用第三种方法;
本来上边几种方式对于处理沉浸式状态栏已经足够了,但是因为出现了万恶的刘海屏手机,在某些机型上,设置FLAG这种方法就会出现问题,如下:
在小米8手机上,当通过设置SYSTEM_UI_FLAG_FULLSCREEN对开屏图页面做沉浸式处理时,发现虽然状态栏隐藏了,但是原状态栏位置上会被黑条占领,而不会像OPPO R17等手机一样,UI可以直接向上延伸。
好在Android P版本为我们提供了解决方法,我们可以通过对Window设置layoutInDisplayCutoutMode来达到我们的目的,先来看一下layoutInDisplayCutoutMode的几种属性
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:默认情况下,全屏窗口不会使用到刘海区域,非全屏窗口可正常使用刘海区域
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:窗口不允许和刘海屏重叠
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES :该窗口始终允许延伸到屏幕短边上的DisplayCutout区域。
利用layoutInDisplayCutoutMode解决Android P 刘海屏状态栏适配问题代码如下:
在代码中设置-----
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
activity.getWindow().setAttributes(lp);
View decorView = activity.getWindow().getDecorView();
int systemUiVisibility = decorView.getSystemUiVisibility();
int flags =View.SYSTEM_UI_FLAG_HIDE_NAVIGATION//隐藏导航栏
| View.SYSTEM_UI_FLAG_FULLSCREEN;//隐藏状态栏
systemUiVisibility |= flags;
activity.getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
在xml中设置theme----
<style name="AppFullTheme" parent="AppTheme">
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowFullscreen">true</item>
</style>
解决了刘海屏状态栏的适配问题后,发现在代码中设置,当手指在屏幕上滑动时,会导致状态栏与导航栏重新出现,而在xml中设置theme却不会有这样的问题。原理尚不明确,后续会继续跟进这个问题。。。
临时解决方案:
在代码中添加设置View.SYSTEM_UI_FLAG_IMMERSIVE,这样只有在状态栏与导航栏区域向内滑动时才会被唤醒。
暂时推荐使用xml设置theme方式