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

Programmatically Change Status Bar Text Color in Android 11 (API 30)

我目前可以在我的基地 activity:

中使用以下内容将状态栏 text 颜色从浅色更新为深色
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 函数,但不清楚如何从文档中实现这一点。有人能指出我正确的方向吗?

对于 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 可以为空,因此 ? 检查。

或者(对于更小的 APIs)你可以使用 WindowInsetControllerCompat:

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

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

我和其他人一样,无法获得 @Pawel 推荐的适用于所有 Android OS 版本的新 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
    }
}