【问题标题】:how to change statusbar color in jetpack compose?如何更改jetpack compose中的状态栏颜色?
【发布时间】:2021-01-07 10:01:46
【问题描述】:

如何在 compose 中使状态栏颜色透明,如下所示:

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

【问题讨论】:

    标签: android-jetpack-compose


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      第 1 步(添加依赖项)=> 版本可能会改变

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

      第 2 步 => 在 theme.kt 文件中

      在下面的函数中根据您的需要更改颜色。

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

      第 3 步 => 在 systemUiController 上,您可以访问您的应用所需的所有类型的自定义,上面一个是 setSystemBarsColor

      的示例

      【讨论】:

      • 如果您只想更改状态栏颜色,也可以使用 systemUiController.setStatusBarColor(color = Color.White)
      【解决方案3】:

      只需采用老式方式并将其添加到themes.xml:

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

      【讨论】:

        【解决方案4】:

        我使用的是在 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
                }
            }
        

        【讨论】:

        • 啊,好旧的弃用警告压制......最好的工艺
        【解决方案5】:

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

        WindowCompat.setDecorFitsSystemWindows(window, false)
        

        这在之前

            setContent{}
        

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

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

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

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

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

        【讨论】:

        • 使用 WindowCompat 导致我的应用程序无法正常运行。我觉得不需要,调整colors.xml和themes.xml就够了
        • 好的,但是请仔细检查您输入的内容,因为没有它,当您从暗屏切换到亮屏时,您可能仍然无法获得所需的输出。
        【解决方案6】:

        我认为其他答案想多了。

        只需检查您的 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>
        

        【讨论】:

          【解决方案7】:

          我用这个:https://stackoverflow.com/a/22192691/9957384

          它可以工作,但也许 compose 有更好的解决方案。 为方便起见,我建议创建一个环境

          【讨论】:

          • 该解决方案是用于更改应用栏而不是设备的状态栏。
          【解决方案8】:

          答案真的很复杂 :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">
          

          【讨论】:

            【解决方案9】:
               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: Boolean = color.luminance() > 0.5f, transformColorForLightContent:(颜色)-> 颜色 = 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
            )
            

            }

            fun SystemUiController(window: Window): SystemUiController { 返回 SystemUiControllerImpl(窗口) }

            /**

            • 一个帮助类,用于优雅地设置 [Window] 的导航和状态栏颜色

            • 基于 API 级别的降级行为。 */ 私有类 SystemUiControllerImpl(private val window: Window) : SystemUiController {

              /**

              • 设置状态栏颜色。

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

                上运行,这可能需要修改
              • 仅支持白色状态栏图标的 API 级别。

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

              • API 23+。

              • @param transformColorForLightContent 一个 lambda,将被调用以转换 [color] if

              • 请求了深色图标但不可用。默认应用黑色稀松布。 */ 覆盖有趣的 setStatusBarColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) { val statusBarColor = 当{ darkIcons && Build.VERSION.SDK_INT transformColorForLightContent(color) 其他 -> 颜色 } window.statusBarColor = statusBarColor.toArgb()

                如果 (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 要设置的期望 [颜色]。如果在

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

              • 和 [Color.Transparent] 将在 API 29+ 上使用,其中首选手势导航或

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

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

              • API 26+。

              • @param transformColorForLightContent 一个 lambda,将被调用以转换 [color] if

              • 请求了深色图标但不可用。默认应用黑色稀松布。 */ 覆盖有趣的 setNavigationBarColor( 颜色: 颜色, darkIcons:布尔值, transformColorForLightContent:(颜色)-> 颜色 ) { val navBarColor = 当{ Build.VERSION.SDK_INT >= 29 -> Color.Transparent // 用于手势导航 darkIcons && Build.VERSION.SDK_INT transformColorForLightContent(color) 其他 -> 颜色 } window.navigationBarColor = navBarColor.toArgb()

                如果 (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() } } }

              /**

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

            /**

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

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

            /**

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

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

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

            【讨论】:

            • 请重新格式化您的答案并将其简化为最小的工作示例
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-08-08
            • 1970-01-01
            • 2021-11-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多