Android主题:在Material3中将状态栏颜色设置为操作栏颜色

20

我正在将应用程序的Material Design主题从V2(1.4.0)迁移到V3(1.5.0)。

Theme.MaterialComponents.DayNight不同,它具有使用Primary颜色作为操作栏的DarkActionBar子样式,Theme.Material3.DayNight没有DarkActionBar子样式。

我无法确定默认设置中操作栏使用的颜色。

这是我的当前应用程序主题的显示方式:

App screenshot

可以看到,我的Primary颜色是蓝色,但是操作栏已自动使用了Primary的阴影/透明度进行上色。操作栏的十六进制颜色表示并非由我定义。我尝试将状态栏设置为我在colors.xml文件中定义的各种蓝色阴影,但是没有一个完美匹配。

有人可以解释操作栏颜色是如何确定的,或者我如何能够将状态栏设置为与操作栏相同的颜色吗?

colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="black">#000000</color>
    <color name="white">#ffffff</color>

    <color name="black_alpha_020">#33000000</color>
    <color name="white_alpha_060">#99ffffff</color>

    <color name="blue_50">#e3f2fd</color>
    <color name="blue_50_bit_black">#E4F0F5</color>
    <color name="blue_100">#bbdefb</color>
    <color name="blue_300">#64b5f6</color>
    <color name="blue_500">#2196f3</color>
    <color name="blue_700">#1976d2</color>
    <color name="blue_a100">#82b1ff</color>

    <color name="blue_black_3_3">#072451</color>
    <color name="blue_black_3_3_bit_black">#031228</color>
    <color name="blue_white_5_6">#fafdff</color>
    <color name="blue_black_5_6">#061929</color>
    <color name="blue_black_10_2">#CEDCE6</color>
    <color name="blue500_black_5_6">#26282A</color>

    <color name="blue_50_alpha_060">#99e3f2fd</color>

    <color name="blue_grey_700">#455a64</color>
    <color name="blue_grey_800">#37474f</color>

    <color name="amber_100">#ffecb3</color>
    <color name="amber_700">#ffa000</color>
    <color name="amber_black_3_4">#401C00</color>

    <color name="red_50">#ffebee</color>
    <color name="red_black_2_3">#3D0909</color>
    <color name="red_900">#b71c1c</color>

    <color name="grey_600">#757575</color>

</resources>

主题.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.SimpleTheme" parent="Theme.Material3.DayNight">
        <!--Color-->
        <item name="colorPrimary">@color/blue_500</item>
        <item name="colorOnPrimary">@color/white</item>
        <item name="colorPrimaryContainer">@color/blue_50</item>
        <item name="colorOnPrimaryContainer">@color/blue_black_3_3</item>

        <item name="colorSecondary">@color/blue_grey_800</item>
        <item name="colorOnSecondary">@color/white</item>
        <item name="colorSecondaryContainer">@color/blue_50_bit_black</item>
        <item name="colorOnSecondaryContainer">@color/blue_black_3_3_bit_black</item>

        <item name="colorTertiary">@color/amber_700</item>
        <item name="colorOnTertiary">@color/white</item>
        <item name="colorTertiaryContainer">@color/amber_100</item>
        <item name="colorOnTertiaryContainer">@color/amber_black_3_4</item>

        <item name="colorError">@color/red_900</item>
        <item name="colorOnError">@color/white</item>
        <item name="colorErrorContainer">@color/red_50</item>
        <item name="colorOnErrorContainer">@color/red_black_2_3</item>

        <item name="android:colorBackground">@color/blue_white_5_6</item>
        <item name="colorOnBackground">@color/blue_black_5_6</item>
        <item name="colorSurface">@color/blue_white_5_6</item>
        <item name="colorOnSurface">@color/blue_black_5_6</item>

        <item name="colorSurfaceVariant">@color/blue_black_10_2</item>
        <item name="colorOnSurfaceVariant">@color/blue500_black_5_6</item>
        <item name="colorOutline">@color/grey_600</item>

        <item name="colorSurfaceInverse">@color/blue_black_5_6</item>
        <item name="colorOnSurfaceInverse">@color/blue_white_5_6</item>
        <item name="colorPrimaryInverse">@color/blue_a100</item>

        <item name="android:navigationBarColor" tools:targetApi="o_mr1">?attr/colorSurface</item>
        <item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">true</item>
    </style>

    <style name="Theme.SimpleTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
</resources>
6个回答

19
使状态栏透明: 主题.xml
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>

主题.xml(夜间)

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

请将您的 activity_main.xml 文件编辑为以下示例代码:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        ...
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        ...>

        <com.google.android.material.MaterialToolbar
        ...
        />

    </com.google.android.material.appbar.AppBarLayout>
    ...
</androidx.coordinatorlayout.widget.CoordinatorLayout>

欲了解更多信息,请查看此文档:https://m3.material.io/components/top-app-bar/implementation/android#collapsing-top-app-bars


2
完美运行 - ci0ccarellia
文档页面找不到。 - kitfist0
@kitfist0 Github 文档:https://github.com/material-components/material-components-android/blob/master/docs/components/TopAppBar.md#collapsing-top-app-bars - Atakan Yildirim
1
这是整个页面上唯一正确的答案。 - undefined

14

使用SurfaceColors类

Action Bar的颜色是带有海拔高度的colorSurface。

如果您想更改状态栏的颜色,请使用SurfaceColors类。此函数还适用于Material 3中的动态着色和日/夜模式。

Kotlin代码:

val color = SurfaceColors.SURFACE_2.getColor(this)
window.statusBarColor = color // Set color of system statusBar same as ActionBar
window.navigationBarColor = color // Set color of system navigationBar same as BottomNavigationView

结果 输入图片描述 谢谢


Material 3中的状态栏不应该有colorSurface,即SURFACE_0吗?示例显示状态栏的颜色显然应与顶部应用栏的颜色相同(SURFACE_0,即colorSurface,除非滚动):https://m3.material.io/components/top-app-bar/specs - Patrick
@Patrick。实现顶部应用栏有两种方式:ActionBar和Toolbar。我的回答基于默认的ActionBar。你可以看到应用栏下面有一个小阴影。而你的评论则是基于Toolbar。这需要手动设置和添加。我们都是正确的。这里是关于它们之间区别的链接。https://developer.android.com/training/appbar/setting-up - FM1024
1
对于Java,请使用getWindow().setStatusBarColor(SurfaceColors.SURFACE_2.getColor(this));,并在themes.xml中设置<item name="android:windowLightStatusBar">true</item>和<item name="android:windowLightStatusBar">false</item>(夜间模式)。 - Roney Thomas

2

对我有效的方法是在themes.xml中执行以下操作。

这适用于浅色和深色主题:

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

0

theme.xml(no-night):

<style name="Theme.AllCodeApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
     <item name="android:statusBarColor" tools:targetApi="l">@color/white</item>
         <item name="actionBarStyle">
            @style/MyActionBarDarkStyle
        </item>
</style>
<style name="MyActionBarDarkStyle" parent="Widget.MaterialComponents.ActionBar.Primary">
        <item name="backgroundColor">@color/white</item>
 </style>

theme.xml(night):

<style name="Theme.AllCodeApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <item name="android:statusBarColor" tools:targetApi="l">@color/teal_200</item>
        <item name="actionBarStyle">
            @style/MyActionBarDarkStyle
        </item>
</style>
<style name="MyActionBarDarkStyle" parent="Widget.MaterialComponents.ActionBar.Primary">
        <item name="backgroundColor">@color/teal_200</item>
</style>

我知道如何设置颜色。我需要弄清楚操作栏自动设置的颜色,并最好使用属性设置状态栏颜色。 - Shahid Thaika
好的,我知道了。我的代码正在更新,请检查一下。 - Meet Bhavsar
我实际上正在使用Material V3(Theme.Material3),而不是V2(Theme.MaterialComponents)。您在代码中使用的父主题已经不存在了。我尝试了与您在代码中类似的东西,但它没有起作用。设置textColor和titleTextColor也没有改变操作栏的样式。不知道是否存在错误。 - Shahid Thaika
请发送您的浅色和深色主题文件。 - Meet Bhavsar
明天我会看。今天我的考试。 - Meet Bhavsar

0

您正在使用的父主题具有属性colorSurface,该属性负责操作栏的背景颜色。但在material3中,会将主要颜色高程应用于表面颜色以创建混合颜色。请参考下面的链接并仔细阅读使用表面颜色部分,您将得到答案。这是链接

由于该颜色是动态生成的,因此您可以使用SurfaceColors Api动态设置应用程序的状态栏颜色。

在Java中,getWindow().setStatusBarColor(SurfaceColors.SURFACE_5.getColor(this));

我以上使用了枚举SURFACE_5作为示例目的,您可以使用从SURFACE_0到SURFACE-5的不同枚举来获取所需的颜色。


0

这对我有用。

将此项添加到您的主题.xml文件中的样式中:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接