Android狀態(tài)欄設(shè)置背景色

一、簡(jiǎn)要說(shuō)明

頂部的有時(shí)間手機(jī)電量展示的叫做 狀態(tài)欄
底部的有三個(gè)虛擬按鍵的叫做導(dǎo)航欄

注意以下討論,基于Android版本11,也就是沒啥版本兼容的考慮
一般都是為了實(shí)現(xiàn)沉浸式的效果

二、一般做法

對(duì)于大多數(shù)的App頁(yè)面來(lái)說(shuō)都是需要沉浸式的。
所以就在Activity上要設(shè)置

WindowCompat.setDecorFitsSystemWindows(window, false)

然后設(shè)置這個(gè)后,內(nèi)容區(qū)域就會(huì)擴(kuò)展到整個(gè)狀態(tài)欄。
一般狀態(tài)欄的背景色要設(shè)置成透明的,否則兩種顏色疊加在一起不好看。

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

接著就需要注意是否會(huì)有重疊的情況,也就是頂部是否需要預(yù)留狀態(tài)欄的高度,避免不好看
高度都是不一樣的,這里可以去讀取高度

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

再接著就是有可能你的內(nèi)容背景色與狀態(tài)欄文字顏色不搭,導(dǎo)致看不清楚
這時(shí)候就需要設(shè)置狀態(tài)欄文字顏色
修改狀態(tài)欄為暗色風(fēng)格,則文字為亮色

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

1 最終在Activity的主題中

    <style name="SampleTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        //修改狀態(tài)欄為透明
        <item name="android:statusBarColor">@android:color/transparent</item>
        //修改狀態(tài)欄為暗色風(fēng)格,則文字為亮色
        <item name="android:windowLightStatusBar">false</item>
        
        //修改導(dǎo)航欄為非半透明
        <item name="android:windowTranslucentNavigation">false</item>
        //修改導(dǎo)航欄為透明
        <item name="android:navigationBarColor">@android:color/transparent</item>
        //修改導(dǎo)航欄忽略對(duì)比度不夠的問題
        <item name="android:enforceNavigationBarContrast">false</item>
    </style>

2 在Compose中可以這么寫

有一個(gè)庫(kù),可以實(shí)現(xiàn)

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

重點(diǎn)看注釋即可

SystemUiController.kt

//rememberSystemUiController實(shí)現(xiàn)類是 AndroidSystemUiController
    override fun setStatusBarColor(
        color: Color,
        darkIcons: Boolean,
        transformColorForLightContent: (Color) -> Color
    ) {
       //這個(gè)則最終調(diào)用的是WindowInsetControllerCompat
        statusBarDarkContentEnabled = darkIcons

      // 這里調(diào)用的是 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) {
                  // 這個(gè)標(biāo)識(shí)說(shuō)是被廢棄了
                    setSystemUiFlag(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                }

                //重點(diǎn)是這個(gè)標(biāo)識(shí)
                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);
        }
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容