本文章分以下内容:
- 沉浸式状态栏的实现
- 沉浸式导航栏的实现
- 适配实现沉浸式状态栏后导致的布局偏移
- 其他常见问题
一、沉浸式状态栏的实现
该方法用于表示内容是否超出至状态栏和底部导航栏显示,false表明超出。(这也就我们实现沉浸式后需要做适配的原因)
WindowCompat.setDecorFitsSystemWindows(window, false)
注意:当使用setDecorFitsSystemWindows()时,注意不要使用View.setSystemUiVisibility(),因为在源码中,对于Android4.1-10的手机仍旧采用了setSystemUiVisibility方法实现沉浸式。
设置状态栏透明
window.statusBarColor = Color.TRANSPARENT
二、沉浸式导航栏的实现
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//当背景透明时去掉灰色蒙层
window.isNavigationBarContrastEnforced = false
}
//导航栏颜色透明
window.navigationBarColor = Color.TRANSPARENT
三、处理状态栏UI与布局内容产生的重叠
实现沉浸式后我们会发现,布局内容与状态栏、底部导航栏叠加在一起了,为了避免应用UI与系统UI产生重叠,所以我们要对其进行偏移。
首先通过这个方法,获取insets。参数填入window.decorView,当然也可以使用位于实现沉浸式的页面的view,
ViewCompat.setOnApplyWindowInsetsListener(view) { view, insets:WindowInsetsCompat ->
}
那么insets具体是什么呢?实际上insets是描述一组用于窗口内容的插入。说人话就是:我们可以从insets中获取包括状态栏,导航栏等系统UI的位置距离,然后用于调整我们的应用UI的位置。接下来我们就来看如何实现
ViewCompat.setOnApplyWindowInsetsListener(view) { view, insets:WindowInsetsCompat ->
val systemWindow=insets.getInsets(WindowInsetsCompat.Type.systemBars() or
WindowInsetsCompat.Type.displayCutout())
//为需要偏移的view设置padding
moveView.setPadding(0,systemWindow.top,0,0)
insets
}
通过inset.getInsets()获取对应的系统UI的信息, 我们也可以通过 “or” 同时获取多种系统栏的距离。例如我们可以同时获取系统的状态栏和刘海屏高度,如果刘海屏的高度更高则返回的是刘海屏的高度。
因为沉浸式所导致的底部布局与导航栏重叠问题也一样迎刃而解了。
view.setPadding(0,0,0,systemWindow.bottom)
WindowInsetsCompat.Type参数解释:
WindowInsetsCompat.Type.ime();//键盘
WindowInsetsCompat.Type.displayCutout();//刘海屏
WindowInsetsCompat.Type.statusBars();//状态栏
WindowInsetsCompat.Type.navigationBars();//导航栏
WindowInsetsCompat.Type.captionBar();//标题栏
WindowInsetsCompat.Type.systemBars();//状态栏,导航栏和标题栏
WindowInsetsCompat.Type.systemGestures();//系统手势
WindowInsetsCompat.Type.mandatorySystemGestures();//强制性系统手势
WindowInsetsCompat.Type.tappableElement();//可点击区域
四、其他常见问题
状态栏字体颜色修改:
//状态栏字体改为白色
WindowCompat.getInsetsController(window,window.decorView).isAppearanceLightStatusBars = false
//状态栏字体改为黑色
WindowCompat.getInsetsController(window,window.decorView).isAppearanceLightStatusBars = true
导航栏按钮颜色修改:
WindowCompat.getInsetsController(window,window.decorView).isAppearanceLightNavigationBars= false
用这个方法的时候会导致状态栏字体变成白色,目前我的解决办法是重新再设置一次状态栏字体颜色,如果你有更好的解决方法欢迎在评论区留言。