StatusBar 状态栏配置

1,090 阅读2分钟

状态栏的设置

状态栏上面的文字显示颜色

        <!-- 改变status bar 文字颜色, true黑色, false白色,API23可用-->
        <item name="android:windowLightStatusBar">true</item>
        <!-- status bar color -->
        <item name="android:statusBarColor">#00000000</item>
        //通过BarColor之间设置 ,例如设置成蓝色,
        window.statusBarColor = Color.Blue
        //android 版本11 遗弃
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR //黑色
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE //白色
        //兼容版本,直接用如下方式
        WindowCompat.getInsetsController(window, window.decorView)
            .isAppearanceLightStatusBars = false

状态栏底色为透明色,适配打孔屏,水滴屏等等

显示效果: 0YIVI{5P82@)3J4D4}THQ4O.png

推荐方式

//false 设置会让状态栏显示在内容之上 全面屏  true 非全面屏
WindowCompat.setDecorFitsSystemWindows(window, false)
//状态栏设置成透明颜色
window.statusBarColor = Color.TRANSPARENT

完整方法

fun setFullScreen(window: Window, conflictView: View? = null) {
    WindowCompat.setDecorFitsSystemWindows(window, false)
    window.statusBarColor = Color.TRANSPARENT
    window.navigationBarColor = Color.TRANSPARENT
    if (conflictView == null) return
    ViewCompat.setOnApplyWindowInsetsListener(conflictView) { view, windowInsets ->
        val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
        // 此处更改的 margin,也可设置 padding,视情况而定
        view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
            topMargin = insets.top
            leftMargin = insets.left
            bottomMargin = insets.bottom
            rightMargin = insets.right
        }
        WindowInsetsCompat.CONSUMED
    }
}

其他方法

以下方法兼容刘海屏等,但是android11被遗弃,同样工具栏toolbar设置间隔

val option = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
window.decorView.systemUiVisibility = option
window.statusBarColor = Color.TRANSPARENT

注意事项:flag 别用SYSTEM_UI_FLAG_FULLSCREEN ,当首次触摸状态栏,会出现状态栏,对于刘海屏等会出现闪屏效果


其他情况

状态栏半透明效果,

状态栏会悬浮于内容content之上,纯色会显示状态栏颜色加深,但是背景如果是图片区别不明显

显示效果:2.png

用windowTranslucentStatus优先级比较高,会导致其他其他设置会无效

<item name="android:windowTranslucentStatus">true</item>

代码中设置

//android  11 遗弃
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

不显示状态栏下的全面屏

通过以下方法不兼容刘海屏,水滴屏等等

<item name="android:windowFullscreen">true</item>
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)

不显示状态栏的全面屏,对于刘海屏会留有黑色区块

val windowInsetsController = WindowCompat.getInsetsController(window, _binding.root)
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE

获取状态栏的高度

在全面屏情况下需要设置Toolbar工具栏的间隔

通过资源文件中的尺寸获取

获取android包下的dimen文件中的status_bar_height资源,然后解析获取尺寸大小 官方不推荐此方法:

  1. 通过name获取资源耗时
  2. 存在资源没有找到风险
    @SuppressLint("DiscouragedApi", "InternalInsetResource")
    fun getStatusBarHeightByResource(): Int {
        Resources.getSystem().apply {
            val resourcesId = getIdentifier("status_bar_height", "dimen", "android")
            return if (resourcesId > 0) getDimensionPixelSize(resourcesId) else {
                Log.e("AppBarUtils", "警告:getStatusBarHeightByResource: not find dimen status_bar_height", )
                0
            }
        }
    }

通过getWindowVisibleDisplayFrame获取

fun getStatusBarHeightByWindow(window: Window): Int {
    val rect = Rect()
    window.decorView.getWindowVisibleDisplayFrame(rect)
    return rect.top
}

通过WindowInsetsCompat获取

fun getStatusBarHeight(window: Window): Int {
    ViewCompat.getRootWindowInsets(window.decorView)?.apply {
        return getInsets(WindowInsetsCompat.Type.statusBars()).top
    }
    return 0
}

优秀的三方库:

ImmersionBar

参考资料:

强烈推荐: Android Detail:Window 篇—— WindowInsets 与 fitsSystemWindow - 掘金 (juejin.cn)

WindowInsetsControllerCompat使用,新方式实现状态栏、导航栏、键盘控制-CSDN博客