Android状态栏设置背景色

2022-12-15  本文已影响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);
        }
    }
上一篇下一篇

猜你喜欢

热点阅读