美文网首页
Android状态栏设置背景色

Android状态栏设置背景色

作者: 艾伦宇 | 来源:发表于2022-12-15 10:50 被阅读0次

    一、简要说明

    顶部的有时间手机电量展示的叫做 状态栏
    底部的有三个虚拟按键的叫做导航栏

    注意以下讨论,基于Android版本11,也就是没啥版本兼容的考虑
    一般都是为了实现沉浸式的效果

    二、一般做法

    对于大多数的App页面来说都是需要沉浸式的。
    所以就在Activity上要设置

    WindowCompat.setDecorFitsSystemWindows(window, false)
    

    然后设置这个后,内容区域就会扩展到整个状态栏。
    一般状态栏的背景色要设置成透明的,否则两种颜色叠加在一起不好看。

    <item name="android:statusBarColor">@android:color/transparent</item>
    

    接着就需要注意是否会有重叠的情况,也就是顶部是否需要预留状态栏的高度,避免不好看
    高度都是不一样的,这里可以去读取高度

    context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    

    再接着就是有可能你的内容背景色与状态栏文字颜色不搭,导致看不清楚
    这时候就需要设置状态栏文字颜色
    修改状态栏为暗色风格,则文字为亮色

    <item name="android:windowLightStatusBar">false</item>
    

    1 最终在Activity的主题中

        <style name="SampleTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
            //修改状态栏为透明
            <item name="android:statusBarColor">@android:color/transparent</item>
            //修改状态栏为暗色风格,则文字为亮色
            <item name="android:windowLightStatusBar">false</item>
            
            //修改导航栏为非半透明
            <item name="android:windowTranslucentNavigation">false</item>
            //修改导航栏为透明
            <item name="android:navigationBarColor">@android:color/transparent</item>
            //修改导航栏忽略对比度不够的问题
            <item name="android:enforceNavigationBarContrast">false</item>
        </style>
    

    2 在Compose中可以这么写

    有一个库,可以实现

        ProvideWindowInsets {
            val systemUiController = rememberSystemUiController()
            SideEffect {
                systemUiController.setStatusBarColor(Color.Transparent, darkIcons = statusDarkIcons)
                systemUiController.setNavigationBarColor(
                    navigationBarColor,
                    darkIcons = navigationDarkIcons,
                    navigationBarContrastEnforced = false
                )
            }
            content()
        }
    
    SystemUiController.setStatusBarColor原理

    重点看注释即可

    SystemUiController.kt

    //rememberSystemUiController实现类是 AndroidSystemUiController
        override fun setStatusBarColor(
            color: Color,
            darkIcons: Boolean,
            transformColorForLightContent: (Color) -> Color
        ) {
           //这个则最终调用的是WindowInsetControllerCompat
            statusBarDarkContentEnabled = darkIcons
    
          // 这里调用的是 PhoneWindow.setStatusBarColor
            window?.statusBarColor = when {
                darkIcons && !windowInsetsController.isAppearanceLightStatusBars -> {
                    // If we're set to use dark icons, but our windowInsetsController call didn't
                    // succeed (usually due to API level), we instead transform the color to maintain
                    // contrast
                    transformColorForLightContent(color)
                }
                else -> color
            }.toArgb()
        }
    
        override var statusBarDarkContentEnabled: Boolean
            get() = windowInsetsController.isAppearanceLightStatusBars
            set(value) {
                windowInsetsController.isAppearanceLightStatusBars = value
            }
    

    WindowInsetControllerCompat.java

            @Override
            public void setAppearanceLightStatusBars(boolean isLight) {
                if (isLight) {
                    if (mWindow != null) {
                      // 这个标识说是被废弃了
                        setSystemUiFlag(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                    }
    
                    //重点是这个标识
                    mInsetsController.setSystemBarsAppearance(
                            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
                            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
                } else {
                    if (mWindow != null) {
                        unsetSystemUiFlag(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                    }
    
                    mInsetsController.setSystemBarsAppearance(
                            0,
                            WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
                }
            }
    

    PhoneWindow.java

        public void setStatusBarColor(int color) {
            mStatusBarColor = color;
            mForcedStatusBarColor = true;
            if (mDecor != null) {
                mDecor.updateColorViews(null, false /* animate */);
            }
            final WindowControllerCallback callback = getWindowControllerCallback();
            if (callback != null) {
                getWindowControllerCallback().updateStatusBarColor(color);
            }
        }
    

    相关文章

      网友评论

          本文标题:Android状态栏设置背景色

          本文链接:https://www.haomeiwen.com/subject/rjvqqdtx.html