如何更改 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">
如何在 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">