前言
已经使用过的沉浸式使用方案有 ImmersionBar 等
实现原理很简单,主要是做异形屏等适配,这里不对适配进行讨论,可看下方链接中有详细说明
原理
设置 Window 相关属性,将 UI 延伸到状态栏,设置背景色
实现
/**
* 沉浸式工具类
*/
object StatusBarHelper {
fun setUp(activity: Activity, statusColor: Int, darkMode: Boolean, isFullScreen : Boolean = false) {
val window = activity.window
val decorView = window.decorView
// Window 的 Flag,不同于 View
var windowVisibility = decorView.systemUiVisibility
//在 Android 5 上设置,5以下不做处理
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
// 两个属性会冲突,需要 clear
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
// 设置状态栏颜色
window.statusBarColor = statusColor
}
// Android 6 上设置
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
windowVisibility = if (darkMode) {
// 白底黑字
windowVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
// 黑底白字
windowVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}
}
if (isFullScreen){
// 全屏,并且使得时间,电量等可见
windowVisibility = windowVisibility or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
decorView.systemUiVisibility = windowVisibility
}
}
状态栏和布局重叠
虽然手动添加了一个占位 View ,但还是出现了重叠,这里查找原因
原因: 设置全屏后,ContentView 的布局延伸到了原来的状态栏位置,所以需要特殊处理
/**
* 处理布局和状态栏重叠
*/
fun with(view : View){
val paddingTop = getStatusBarHeight(view.context) + view.paddingTop
view.setPadding(0, paddingTop, 0, 0)
}
fun getStatusBarHeight(ctx : Context) : Int {
var statusBarHeight = 0
val resourceId: Int = ctx.getResources().getIdentifier("status_bar_height", "dimen", "android")
if (resourceId > 0) {
statusBarHeight = ctx.getResources().getDimensionPixelSize(resourceId)
}
return statusBarHeight
}
给顶部的 View 设置一个刚好状态栏大小的内部边距就可以了
测试效果
// 在 Activity.onCreate() 中调用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mian)
StatusBarHelper.setUp(this,Color.WHITE,true,true)
StatusBarHelper.with(findViewById(R.id.ll_container))
}