blow
blow

Reputation: 13209

Android, setting the theme in the style does not work

I know that

A style specifies attributes for a particular type of view. For example, one style might specify a button's attributes. Every attribute you specify in a style is an attribute you could set in the layout file. By extracting all the attributes to a style, it's easy to use and maintain them across multiple widgets.

A theme defines a collection of named resources which can be referenced by styles, layouts, widgets, and so on. Themes assign semantic names, like colorPrimary, to Android resources.

So, i suppose that I can set the theme attribute from a style file.

Why doesn't this work?

<!-- Customize your theme here. -->
<item name="toolbarStyle">MyToolbarStyle</item>
...

<style name="MyToolBarTheme" parent="ThemeOverlay.MaterialComponents.Toolbar.Primary">
    <item name="android:textColorPrimary">@color/white</item>
    <item name="colorOnPrimary">@color/white</item>
</style>

<style name="MyToolbarStyle" parent="Widget.AppCompat.Toolbar">
    <item name="theme">@style/MyToolBarTheme</item>
</style>

Instead this works correctly:

    <com.google.android.material.appbar.MaterialToolbar
    android:id="@+id/homeToolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    android:theme="@style/MyToolBarTheme" />

Upvotes: 1

Views: 1178

Answers (1)

blow
blow

Reputation: 13209

I found that the theme attribute is not set if the defining style is itself set by a theme, but only when the style is set in the designer.

The materialThemeOverlay attribute on the other hand works correctly and actually applies the theme.

I found a comment in a material design theme definition:

<style name="Widget.MaterialComponents.Toolbar.Primary">
<item name="android:elevation" ns2:ignore="NewApi">@dimen/design_appbar_elevation</item>
<item name="android:background">?attr/colorPrimary</item>
<item name="titleTextColor">?attr/colorOnPrimary</item>
<item name="subtitleTextColor">@color/material_on_primary_emphasis_medium</item>
<!-- Note: this theme overlay will only work if the style is applied directly to a Toolbar. -->
<item name="android:theme">@style/ThemeOverlay.MaterialComponents.Toolbar.Primary</item>

So, in my case, this works as expected:

<!-- Customize your theme here. -->
<item name="toolbarStyle">MyToolbarStyle</item>
...

<style name="MyToolBarTheme" parent="ThemeOverlay.MaterialComponents.Toolbar.Primary">
    <item name="android:textColorPrimary">@color/white</item>
    <item name="colorOnPrimary">@color/white</item>
</style>

<style name="MyToolbarStyle" parent="Widget.AppCompat.Toolbar">
    <item name="materialThemeOverlay">@style/MyToolBarTheme</item>
</style>

Update

How the style and theme are applied to the views is highly dependent on how the views are implemented.

materialThemeOverlay is used inside the material view source code, so to know exactly the effect of the theme style or attribute, you should look into the view source code.

Upvotes: 3

Related Questions