Reputation: 13209
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
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
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