Android,在 theme.xml 文件中设置工具栏样式

Android, set Toolbar style in theme.xml file

我正在尝试在我的应用程序中自定义工具栏的外观。

目标
我想设置工具栏的标题颜色和背景颜色。
我了解了 Theme and Style 是如何工作的,所以我能够尝试一些解决方案。 我发现标题颜色由 app:titleTextColor 属性 管理,背景颜色由 android:background 属性管理。


前提
要了解如何操作,有必要了解我们需要修改的小部件的样式是如何管理的。

基本工具栏样式在 Widget.MaterialComponents.Toolbar 样式中定义如下。

<style name="Widget.MaterialComponents.Toolbar" parent="Widget.AppCompat.Toolbar">
    <item name="titleTextAppearance">?attr/textAppearanceHeadline6</item>
    <item name="titleTextColor">?android:attr/textColorPrimary</item>
    <item name="subtitleTextAppearance">?attr/textAppearanceSubtitle1</item>
    <item name="subtitleTextColor">?android:attr/textColorSecondary</item>
    <!-- Overrides minimum height in landscape to avoid headline6 and subtitle1 height concerns. -->
    <item name="android:minHeight">@dimen/mtrl_toolbar_default_height</item>
    <item name="maxButtonHeight">@dimen/mtrl_toolbar_default_height</item>
</style>

这里titleTextColor的值设置为?android:attr/textColorPrimary


所以我的第一次尝试只是在我的应用程序主题中添加 android:textColorPrimary 属性的 ovverride。

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <!-- Primary brand color. -->
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorPrimaryVariant">@color/purple_700</item>
    <item name="colorOnPrimary">@color/white</item>
    <!-- Secondary brand color. -->
    <item name="colorSecondary">@color/teal_200</item>
    <item name="colorSecondaryVariant">@color/teal_700</item>
    <item name="colorOnSecondary">@color/black</item>
    <!-- Status bar color. -->
    <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>

    <!-- Customize your theme here. -->
    <item name="android:textColorPrimary">@color/white</item>
</style>

结果:有效。

为了同时设置背景,我决定创建自定义工具栏样式以放置背景定义,因此我更改了如下主题。

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    ...    
    <!-- Customize your theme here. -->
    <item name="toolbarStyle">@style/MyToolbarStyle</item>
</style>
<style name="MyToolbarStyle" parent="Widget.MaterialComponents.Toolbar">
    <item name="android:textColorPrimary">@color/white</item>
    <item name="android:background">?attr/colorPrimary</item>
</style>

结果: 这行不通。 android:background 已应用,但 android:textColorPrimary 未应用。

直接在 MyToolbarStyle 中设置 titleTextColor 的值。

<style name="MyToolbarStyle" parent="Widget.MaterialComponents.Toolbar">
    <item name="titleTextColor">?attr/colorOnPrimary</item>
    <item name="android:background">?attr/colorPrimary</item>
</style>

我还尝试设置我覆盖 Android attribute:textColorPrimary 的工具栏主题,如下所示。

<style name="Base_ToolbarStyle" parent="Widget.MaterialComponents.Toolbar">
    <item name="android:background">?attr/colorPrimary</item>
    <item name="android:theme">@style/Base_ToolbarTheme</item>
</style>

<style name="Base_ToolbarTheme">
    <item name="android:textColorPrimary">@color/white</item>
    <item name="android:textColorSecondary">@color/white</item>
</style>

结果:这个也不行

现在我对我的测试结果有点困惑。

为什么无法覆盖自定义样式中的 android:textColorPrimary

要应用 style,您可以使用(toolbarStyle 属性将此样式应用于所有 Toolbarstyle属性:

   <androidx.appcompat.widget.Toolbar
         style="@style/MyToolbarStyle"

与:

<style name="MyToolbarStyle" parent="Widget.MaterialComponents.Toolbar">
    <item name="titleTextColor">?attr/colorOnPrimary</item>
    <item name="android:background">?attr/colorPrimary</item>
</style>

因为titleTextColor是在Toolbar中定义的属性。

要应用主题覆盖,您可以使用android:theme属性:

   <androidx.appcompat.widget.Toolbar
        android:theme="@style/MyToolbarThemeOverlay"

<style name="MyToolbarThemeOverlay">
    <item name="android:textColorPrimary">@color/white</item>
</style>

因为 android:textColorPrimary 是在主题级别定义的属性。

如果您想直接覆盖样式中的主题属性,您必须使用 materialThemeOverlay 属性:

<style name="MyToolbarStyle" parent="Widget.MaterialComponents.Toolbar">
    <item name="android:background">?attr/colorPrimary</item>
    <item name="materialThemeOverlay">@style/MyToolbarThemeOverlay</item>
</style>

通过使用 AppCompat Material 工具栏 androidx.appcompat.widget.Toolbar,我做了以下定义来自定义主题中的工具栏

给定布局文件中的这个工具栏:

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/MyAppTheme.AppBarOverlay">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        app:popupTheme="@style/MyAppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>

themes.xml 中定义工具栏样式:

<style name="MyAppTheme.Toolbar" parent="Widget.MaterialComponents.Toolbar">
    <!-- Add custom stuff here -->
    <item name="android:background" tools:targetApi="l">@color/dark_primary</item>
    <item name="background">@color/dark_primary</item>
</style>

并在 themes.xml 中添加叠加样式:

<style name="MyAppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="MyAppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

然后在应用主题中应用:

<style name="MyAppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    ...
    <item name="android:toolbarStyle" tools:targetApi="l">@style/MyAppTheme.Toolbar</item>
    <item name="toolbarStyle">@style/MyAppTheme.Toolbar</item>
    ...
</style>