When should one use Theme.AppCompat vs ThemeOverlay.AppCompat?
Asked Answered
C

2

125

There are the following Theme.AppCompat classes:

Theme.AppCompat
Theme.AppCompat.Light
Theme.AppCompat.Light.DarkActionBar
Theme.AppCompat.NoActionBar
Theme.AppCompat.Light.NoActionBar
Theme.AppCompat.DialogWhenLarge
Theme.AppCompat.Light.DialogWhenLarge
Theme.AppCompat.Dialog
Theme.AppCompat.Light.Dialog
Theme.AppCompat.CompactMenu

and the following ThemeOverlay.AppCompat classes:

ThemeOverlay.AppCompat
ThemeOverlay.AppCompat.Light
ThemeOverlay.AppCompat.Dark
ThemeOverlay.AppCompat.ActionBar
ThemeOverlay.AppCompat.Dark.ActionBar

Why would one use ThemeOverlay.AppCompat.light vs Theme.AppCompat.Light for example? I see that there are much less attributes defined for ThemeOverlay -- I am curious what the intended use case for ThemeOverlay is.

Cressi answered 1/12, 2014 at 22:20 Comment(0)
M
75

Per this Theme vs Style blog post by the creator of AppCompat:

[ThemeOverlays] are special themes which overlay the normal Theme.Material themes, overwriting relevant attributes to make them either light/dark.

ThemeOverlay + ActionBar

The keen eyed of you will also have seen the ActionBar ThemeOverlay derivatives:

  • ThemeOverlay.Material.Light.ActionBar
  • ThemeOverlay.Material.Dark.ActionBar

These should only be used with the Action Bar via the new actionBarTheme attribute, or directly set on your Toolbar.

The only things these currently do differently to their parents is that they change the colorControlNormal to be android:textColorPrimary, thus making any text and icons opaque.

Memoir answered 1/12, 2014 at 22:28 Comment(1)
Hey Ian, I'm developing for Android since the the Beta times of Android 1, but I really never fully understood the theming. It's always trail and error. Did you, Chet or anyone else of the UI Toolkit Team held a good talk about this? if not that might be a good idea for the next I/O.Eolanda
T
180

Theme.AppCompat is used to set the global theme for the entire app. ThemeOverlay.AppCompat is used to override (or "overlay") that theme for specific views, especially the Toolbar.

Let's look at an example for why this is necessary.

App themes with an ActionBar

The ActionBar is normally shown in an app. I can choose it's color by setting the colorPrimary value. However, changing the theme changes the color of the text on the ActionBar.

<style name="AppTheme" parent="Theme.AppCompat">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

enter image description here

Since my primary color is dark blue, I should probably use one of the themes that uses a light text color in the action bar because the black text is hard to read.

Hiding the ActionBar and using a Toolbar

The whole point of using Theme.AppCompat rather than Theme.Material is so that we can allow older versions of Android to use our material design theme. The problem is that older versions of Android don't support the ActionBar. Thus, the documentation recommends hiding the ActionBar and adding a Toolbar to your layout. To hide the ActionBar we have to use one of the NoActionBar themes. The following images show the Toolbar with the ActionBar hidden.

enter image description here

But what if I want something like a Light theme with a DarkActionBar? Since I have to use NoActionBar, that isn't an option.

Overriding the App Theme

Here is where ThemeOverlay comes in. I can specify the Dark ActionBar theme in my Toolbar xml layout.

<android.support.v7.widget.Toolbar
    ...
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

This finally allows us to have the effect we want. The Dark.ActionBar theme overlays the Light app theme for this particular occasion.

enter image description here

  • App Theme: Theme.AppCompat.Light.NoActionBar
  • Toolbar Theme: ThemeOverlay.AppCompat.Dark.ActionBar

If you wanted the popup menu to be light you could add this:

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

Further Study

I learned this through experimentation and through reading the following articles.

Turkic answered 6/9, 2016 at 8:46 Comment(3)
How to make status bar transparent when using Themeoverlay?Snappy
I'm wondering how to achieve this with the new MaterialToolbarInfrasonic
@David, I'm mostly working with Flutter now, so I haven't kept up on new Android developments. If you find the answer feel free to come back here and leave a comment, edit my answer, or add your own answer.Turkic
M
75

Per this Theme vs Style blog post by the creator of AppCompat:

[ThemeOverlays] are special themes which overlay the normal Theme.Material themes, overwriting relevant attributes to make them either light/dark.

ThemeOverlay + ActionBar

The keen eyed of you will also have seen the ActionBar ThemeOverlay derivatives:

  • ThemeOverlay.Material.Light.ActionBar
  • ThemeOverlay.Material.Dark.ActionBar

These should only be used with the Action Bar via the new actionBarTheme attribute, or directly set on your Toolbar.

The only things these currently do differently to their parents is that they change the colorControlNormal to be android:textColorPrimary, thus making any text and icons opaque.

Memoir answered 1/12, 2014 at 22:28 Comment(1)
Hey Ian, I'm developing for Android since the the Beta times of Android 1, but I really never fully understood the theming. It's always trail and error. Did you, Chet or anyone else of the UI Toolkit Team held a good talk about this? if not that might be a good idea for the next I/O.Eolanda

© 2022 - 2024 — McMap. All rights reserved.