一、4.0以下系统不支持更改状态栏,无法沉浸式
二、4.0--5.0系统通过FLAG_TRANSLUCENT_STATUS设置全屏并且状态栏透明,支持沉浸式,可以填充和状态栏同高的View,通过更改该View颜色达到更改状态栏背景色效果,原生系统不支持状态栏图标及颜色更改。
- 小米、魅族系统状态栏透明
- 原生系统状态栏自上而下由黑至透明渐变
Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT -> {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
var statusBarView: View? = window.decorView.findViewWithTag("ghStatusBarView")
if (statusBarView == null) {
statusBarView = StatusBarView(window.context)
statusBarView.setTag("ghStatusBarView")
val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT)
params.gravity = Gravity.TOP
statusBarView.setLayoutParams(params)
(window.decorView as? ViewGroup)?.addView(statusBarView)
}
statusBarView.backgroundColor = color
}
由于原生系统不支持修改状态栏图标字体颜色,如果标题栏颜色接近于白色导致状态栏图标文字不明显,可以将状态栏背景色设置成半透明色如#2B2B2B2B否则这设置成透明即可
三、5.0--6.0状态栏支持修改颜色,支持沉浸式,原生系统不支持修改图标字体颜色
- 小米、魅族系统状态栏透明
- 原生系统状态栏半透明色
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = color
}
由于原生系统不支持修改状态栏图标字体颜色,如果标题栏颜色接近于白色导致状态栏图标文字不明显,可以将状态栏背景色设置成半透明色如#2B2B2B2B否则这设置成透明即可
四、6.0以上系统支持修改状态栏背景、图标字体颜色(黑色或白色),支持沉浸式
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ->{
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.TRANSPARENT
if (isDark) {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
}
五、小米系统
@SuppressLint("PrivateApi")
private fun miuiSetStatusBarMode(window: Window, dark: Boolean): Boolean {
var result = false
val clazz = window.javaClass
try {
val layoutParams = Class.forName("android.view.MiuiWindowManager\$LayoutParams")
val field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE")
val darkModeFlag = field.getInt(layoutParams)
val extraFlagField = clazz.getMethod("setExtraFlags", Int::class.javaPrimitiveType, Int::class.javaPrimitiveType)
setStateBarBg(window, Color.TRANSPARENT)
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag)//状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag)//清除黑色字体
}
result = true
//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
androidMSetStatusBarMode(window, dark)
} catch (e: Exception) {
Timber.e("**MIUI设置状态栏异常:${e.message}")
}
return result
}
}
其中setStateBarBg方法设置状态栏背景为步骤二和步骤三,androidMSetStatusBarMode方法为步骤四
六、魅族系统
private fun flymeSetStatusBarMode(window: Window, dark: Boolean): Boolean {
var result = false
try {
val lp = window.attributes
val darkFlag = WindowManager.LayoutParams::class.java.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON")
val meizuFlags = WindowManager.LayoutParams::class.java.getDeclaredField("meizuFlags")
setStateBarBg(window, Color.TRANSPARENT)
darkFlag.isAccessible = true
meizuFlags.isAccessible = true
val bit = darkFlag.getInt(null)
var value = meizuFlags.getInt(lp)
value = if (dark) {
value or bit
} else {
value and bit.inv()
}
meizuFlags.setInt(lp, value)
window.attributes = lp
result = true
} catch (e: Exception) {
Timber.e("**Flyme设置状态栏异常:${e.message}")
}
return result
}
其中setStateBarBg方法设置状态栏背景为步骤二和步骤三
总结:先进行小米、魅族系统进行设置如果失败则进行原生系统规则进行适配