如何更改 Jetpack Compose 中的状态栏颜色?

how to change statusbar color in jetpack compose?

如何在 compose 中使状态栏颜色透明:

它有相同的颜色,但有一点阴影。

我用这个:

它有效,但也许在 compose 中有更好的解决方案。 为了方便起见,我建议创建一个 Ambient

我使用在 Jetpack Compose 示例中找到的这段代码。这对我来说可以。根据自己的喜好调整即可。

@Composable
fun SystemUi(windows: Window) =
    MaterialTheme {
        windows.statusBarColor = MaterialTheme.colors.surface.toArgb()
        windows.navigationBarColor = MaterialTheme.colors.surface.toArgb()

        @Suppress("DEPRECATION")
        if (MaterialTheme.colors.surface.luminance() > 0.5f) {
            windows.decorView.systemUiVisibility = windows.decorView.systemUiVisibility or
                    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        }

        @Suppress("DEPRECATION")
        if (MaterialTheme.colors.surface.luminance() > 0.5f) {
            windows.decorView.systemUiVisibility = windows.decorView.systemUiVisibility or
                    View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
        }
    }
   def version = "0.4.1"
implementation "dev.chrisbanes.accompanist:accompanist-coil:$version"
implementation "dev.chrisbanes.accompanist:accompanist-insets:$version"


class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    WindowCompat.setDecorFitsSystemWindows(window, false)
    setContent {
        // A surface container using the 'background' color from the theme
        val systemUiController = remember { SystemUiController(window) }
        Providers(SysUiController provides systemUiController) {
            ProvideWindowInsets {
                val sysUiController = SysUiController.current

                onCommit(sysUiController, LightColorPalette2.uiBackground) {
                    sysUiController.setSystemBarsColor(
                        color = LightColorPalette2.uiBackground.copy(alpha = AlphaNearOpaque)
                    )
                }
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}

}

你还需要这个文件:

package com.example.myjetsnack

进口android.os.Build 导入 android.view.View 进口 android.view.Window 进口 androidx.compose.runtime.staticAmbientOf 进口 androidx.compose.ui.graphics.Color 进口 androidx.compose.ui.graphics.compositeOver 进口 androidx.compose.ui.graphics.luminance 导入 androidx.compose.ui.graphics.toArgb

接口 SystemUiController { 有趣的 setStatusBarColor( 颜色: 颜色, darkIcons: 布尔值 = color.luminance() > 0.5f, transformColorForLightContent:(颜色)-> Color = BlackScrimmed )

fun setNavigationBarColor(
    color: Color,
    darkIcons: Boolean = color.luminance() > 0.5f,
    transformColorForLightContent: (Color) -> Color = BlackScrimmed
)

fun setSystemBarsColor(
    color: Color,
    darkIcons: Boolean = color.luminance() > 0.5f,
    transformColorForLightContent: (Color) -> Color = BlackScrimmed
)

}

有趣的 SystemUiController(window: Window): SystemUiController { returnSystemUiControllerImpl(window) }

/**

  • 一个助手 class,用于为 [Window] 优雅地设置导航和状态栏颜色

  • 基于 API 级别的有辱人格的行为。 */ private class SystemUiControllerImpl(private val window: Window) : SystemUiController {

    /**

    • 设置状态栏颜色。

    • @param color 要设置的期望[颜色]。如果 运行 on

      这可能需要修改
    • API只支持白色状态栏图标的级别

    • @param darkIcons 深色状态栏图标是否更可取。仅适用于

    • API 23+.

    • @param transformColorForLightContent 如果

      将被调用以转换 [color] 的 lambda
    • 已请求深色图标,但不可用。默认应用黑色稀松布。 */ 覆盖乐趣 setStatusBarColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) { val statusBarColor = 当 { darkIcons && Build.VERSION.SDK_INT < 23 -> transformColorForLightContent(颜色) 其他 -> 颜色 } window.statusBarColor = statusBarColor.toArgb()

      if (Build.VERSION.SDK_INT >= 23) { @Suppress("弃用") 如果(暗图标){ window.decorView.systemUiVisibility = window.decorView.systemUiVisibility 或 View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR } 别的 { window.decorView.systemUiVisibility = window.decorView.systemUiVisibility 和 View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() } } }

    /**

    • 设置导航栏颜色。

    • @param color 要设置的期望[颜色]。如果 运行 on

      这可能需要修改
    • API只支持白色导航栏图标的级别。此外,这将被忽略

    • 和 [Color.Transparent] 将用于 API 29+ 首选手势导航或

    • 系统UI在其他导航模式下自动应用背景保护。

    • @param darkIcons 深色导航栏图标是否更可取。仅适用于

    • API 26+.

    • @param transformColorForLightContent 如果

      将被调用以转换 [color] 的 lambda
    • 已请求深色图标,但不可用。默认应用黑色稀松布。 */ 覆盖乐趣 setNavigationBarColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) { val navBarColor = 当 { Build.VERSION.SDK_INT >= 29 -> Color.Transparent // 对于手势导航 darkIcons && Build.VERSION.SDK_INT < 26 -> transformColorForLightContent(颜色) 其他 -> 颜色 } window.navigationBarColor = navBarColor.toArgb()

      if (Build.VERSION.SDK_INT >= 26) { @Suppress("弃用") 如果(暗图标){ window.decorView.systemUiVisibility = window.decorView.systemUiVisibility 或 View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR } 别的 { window.decorView.systemUiVisibility = window.decorView.systemUiVisibility 和 View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv() } } }

    /**

    • 将状态栏和导航栏设置为[颜色]。
    • @see setStatusBarColor
    • @see setNavigationBarColor */ 覆盖乐趣 setSystemBarsColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) { setStatusBarColor(颜色,darkIcons,transformColorForLightContent) setNavigationBarColor(颜色,darkIcons,transformColorForLightContent) } }

/**

  • 持有当前 [SysUiController] 的 [androidx.compose.runtime.Ambient]。默认为
  • 无操作控制器;消费者应该[提供][androidx.compose.runtime.Providers]一个真实的。 */ val SysUiController = staticAmbientOf { 假系统用户界面控制器 }

private val BlackScrim = Color(0f, 0f, 0f, 0.2f) // 20% 不透明黑色 private val BlackScrimmed: (Color) -> Color = { original -> BlackScrim.compositeOver(原创) }

/**

  • 一个虚假的实现,用作默认值或用于预览。 */ 私有对象 FakeSystemUiController : SystemUiController { 覆盖乐趣 setStatusBarColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) = 单位

    覆盖有趣的 setNavigationBarColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) = 单位

    覆盖有趣的 setSystemBarsColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) = 单位 }

用老办法把这个加到themes.xml:

<item name="android:windowTranslucentStatus">true</item>

简单的答案是: 前往您的MainActivity.kt,然后输入这些代码

WindowCompat.setDecorFitsSystemWindows(window, false)

这个在

之前
    setContent{}

然后前往您的值文件夹,打开 colors.xml 并创建

<color name="transparent">#00000000</color>

转到主题 open themes.xml 和 themes.xml(night) 并将此代码放在两个文件中,在其中一个有颜色的样式标签中。

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

这是在 Android 上创建透明状态栏的简单方法。

Google 刚刚创建了一个名为 accompanist.
的库 您可以在这里找到它:https://github.com/google/accompanist

它包含多个对 Jetpack Compose 有用的库,其中有一个系统 UI 控制器,您可以使用它来更改状态栏颜色。

文档 - https://google.github.io/accompanist/systemuicontroller/

Step 1 (add dependency) => version may change

implementation "com.google.accompanist:accompanist-systemuicontroller:0.17.0"

Step 2 => inside theme.kt file

change the colors according to your need in the functions below.

val systemUiController = rememberSystemUiController()
if(darkTheme){
    systemUiController.setSystemBarsColor(
        color = Color.Transparent
    )
}else{
    systemUiController.setSystemBarsColor(
        color = Color.White
    )
}

Step 3 => ON systemUiController you can acces all types of customizations u need for you app above one is a sample for setSystemBarsColor

我认为其他答案想多了。

看看你的src/main/res/values-night/themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.HelloWorld" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        ...
        <item name="colorPrimaryVariant">@color/black</item>
        ...

        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
    </style>
</resources>

答案真的很复杂:o !!! 您可以从样式 xml 更改应用程序的样式,仅此而已。 这是来自 https://github.com/android/compose-samples/tree/main/Rally

的示例
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Rally" parent="Theme.MaterialComponents.NoActionBar">
    <item name="android:statusBarColor">@color/statusBarColor</item>
    <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
    <item name="android:windowBackground">?attr/colorSurface</item>
</style>

这里负责改变状态栏颜色的那一行是

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

但您还必须考虑状态栏内的文本。例如,如果您将颜色设置为黑色,并且您没有指明所选颜色为深色,则里面的文本将是黑色的,因此它是不可见的。要解决此问题,如果所选颜色为深色,则必须将以下属性设置为 false,否则为 true。

<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>

重要提示:不要忘记将主题属性添加到您的清单文件中:

    <application
    ...
    android:theme="@style/Theme.Rally">