在 Android 11 (API 30) 中以编程方式更改状态栏文本颜色

Posted

技术标签:

【中文标题】在 Android 11 (API 30) 中以编程方式更改状态栏文本颜色【英文标题】:Programmatically Change Status Bar Text Color in Android 11 (API 30) 【发布时间】:2021-12-12 11:07:57 【问题描述】:

我目前可以在我的基本活动中使用以下内容将状态栏 文本 颜色从浅色更新为深色:

private fun toggleStatusBarTextColor(light: Boolean) 
    // clear any existing flags
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
    if(light) 
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
     else 
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
    

systemUiVisibility 现在在 API 30 上显示为已弃用,尽管已弃用的方法暂时仍会起作用,但我更愿意用更新的方法替换它们来完成此操作。我已经读到我们现在应该使用 WindowInsetsController 函数,但不清楚如何从文档中完成此操作。有人能指出我正确的方向吗?

【问题讨论】:

【参考方案1】:

对于 API 30,您可以使用 WindowInsetsController.setSystemBarsAppearance (int appearance, int mask):

使状态栏变亮:

window.insetsController?.setSystemBarsAppearance(
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
)

清除标志:

window.insetsController?.setSystemBarsAppearance(
        0,
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
)

请注意,getInsetsController 可以为空,因此需要检查 ?

您也可以使用WindowInsetControllerCompat

val windowInsetController = ViewCompat.getWindowInsetsController(window.decorView)
windowInsetController?.isAppearanceLightStatusBars = true // or false

注意:如果清除标志不起作用,请检查 window.decorView.windowSystemUiVisibility 的值 - 如果它包含 View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,这意味着您的视图层次结构包含一个带有此标志的视图,该标志被传播并影响 systemUiVisibility 计算。

【讨论】:

无法将文本设置为白色【参考方案2】:

我和其他人一样,无法获得@Pawel 推荐的适用于所有 android 操作系统版本的新 API。不幸的是,我发现我必须同时使用旧 API 和新 API 才能使其在 Android 11 及更低版本上运行:

fun setStatusBarLightText(window: Window, isLight: Boolean) 
    setStatusBarLightTextOldApi(window, isLight)
    setStatusBarLightTextNewApi(window, isLight)



private fun setStatusBarLightTextOldApi(window: Window, isLight: Boolean) 
    val decorView = window.decorView
    decorView.systemUiVisibility =
        if (isLight) 
            decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
         else 
            decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        


private fun setStatusBarLightTextNewApi(window: Window, isLightText: Boolean) 
    ViewCompat.getWindowInsetsController(window.decorView)?.apply 
        // Light text == dark status bar
        isAppearanceLightStatusBars = !isLightText
    

【讨论】:

setStatusBarLightTextNewApi 帮助我用灰色图标将状态栏设为白色

以上是关于在 Android 11 (API 30) 中以编程方式更改状态栏文本颜色的主要内容,如果未能解决你的问题,请参考以下文章

地理定位 API 在 android 中以本地语言显示地址

在 Kivy 的 API 30 (Android 11) 中读取和写入文件

如何在没有系统确认对话框的情况下删除 Android 11 (API 30) 上的文件?

在 Android 11 (API 30) 上检测“提高位置准确性”开/关状态

在 android 10/11 (api 29/30) 下是不是仍然可以破坏性地修改您不拥有的文件?

来自带有 API 30 (android 11) 的三星物理模拟器的错误 Android 11 -> java.net.SocketTimeoutException