blow
blow

Reputation: 13209

Android, set Toolbar style in theme.xml file

I am trying to customize the look of Toolbar in my app.

Target
I would like to set the title color and the background color of the Toolbar.
I read about how Theme and Style works, so I was able to try some solutions. I found out that title color is managed by app:titleTextColor property and the background color from the android:background attribute.


Premise
To know how to act it is necessary to know how the style of the widget that we need to modify is managed.

The base Toolbar style is defined in the Widget.MaterialComponents.Toolbar style as below.

<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>

Here the value of titleTextColor is set to ?android:attr/textColorPrimary.


So my first attempt was simply to add the ovverride of android:textColorPrimary attribute in my app theme.

<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>

Result: This works.

To also set the background I decided to create a custom Toolbar style where to put the background definition, so I changed my theme as below.

<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>

Result: This does not works. The android:background is applied but the android:textColorPrimary not.

Setting the value of titleTextColor directly inside MyToolbarStyle works.

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

I also tried to set the toolbar theme where I override the Android attribute:textColorPrimary, as below.

<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>

Result: This does not works too.

Now I am a bit confused from the outcome of my tests.

Why is it not possible to override the android:textColorPrimary in the custom style?

Upvotes: 2

Views: 1774

Answers (2)

Tommy K.
Tommy K.

Reputation: 96

With using the AppCompat Material Toolbar androidx.appcompat.widget.Toolbar, I have made the following definitions to customize the Toolbar in a theme

Given this toolbar in a layout file:

<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>

Define a toolbar style in 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>

And also add the overlay styles in themes.xml:

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

And then apply in app theme:

<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>

Upvotes: 0

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363825

To apply a style you can use (and the toolbarStyle attribute applies this style to all the Toolbar) the style attribute:

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

with:

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

because titleTextColor is a property defined in the Toolbar.

To apply a theme overlay you can use the android:theme attribute:

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

with

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

because android:textColorPrimary is an attribute defined at theme level.

If you want to override a theme attribute directly in a style you have to use the materialThemeOverlay attribute:

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

Upvotes: 2

Related Questions