Quand faut-il utiliser Theme.AppCompat vs ThemeOverlay.AppCompat?

114

Il existe les classes Theme.AppCompat suivantes:

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

et les classes ThemeOverlay.AppCompat suivantes:

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

Pourquoi utiliser ThemeOverlay.AppCompat.light vs Theme.AppCompat.Light par exemple? Je vois qu'il y a beaucoup moins d'attributs définis pour ThemeOverlay - je suis curieux de savoir quel est le cas d'utilisation prévu pour ThemeOverlay.

Brendan Weinstein
la source

Réponses:

71

Selon cet article de blog Theme vs Style par le créateur d'AppCompat:

[ThemeOverlays] sont des thèmes spéciaux qui superposent les thèmes Theme.Material normaux, écrasant les attributs pertinents pour les rendre clairs / foncés.

ThemeOverlay + ActionBar

Les plus fervents d'entre vous auront également vu les dérivés ActionBar ThemeOverlay:

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

Ceux-ci ne doivent être utilisés qu'avec la barre d'action via le nouvel actionBarThemeattribut, ou directement définis dans votre barre d'outils.

La seule chose qu'ils font actuellement différemment de leurs parents est qu'ils changent le colorControlNormalpour être android:textColorPrimary, rendant ainsi le texte et les icônes opaques.

ianhanniballake
la source
155

Theme.AppCompat est utilisé pour définir le thème global pour l'ensemble de l'application. ThemeOverlay.AppCompat est utilisé pour remplacer (ou "superposer") ce thème pour des vues spécifiques, en particulier la barre d'outils.

Regardons un exemple pour expliquer pourquoi cela est nécessaire.

Thèmes d'application avec une ActionBar

L'ActionBar est normalement affichée dans une application. Je peux choisir sa couleur en définissant la colorPrimaryvaleur. Cependant, la modification du thème modifie la couleur du texte sur l'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>

entrez la description de l'image ici

Étant donné que ma couleur principale est le bleu foncé, je devrais probablement utiliser l'un des thèmes qui utilise une couleur de texte claire dans la barre d'action car le texte noir est difficile à lire.

Masquer l'ActionBar et utiliser une barre d'outils

L'intérêt d'utiliser Theme.AppCompat plutôt que Theme.Material est de permettre aux anciennes versions d'Android d'utiliser notre thème de conception matérielle. Le problème est que les anciennes versions d'Android ne prennent pas en charge l'ActionBar. Ainsi, la documentation recommande de masquer l'ActionBar et d'ajouter une barre d'outils à votre mise en page. Pour masquer l'ActionBar, nous devons utiliser l'un des NoActionBarthèmes. Les images suivantes montrent la barre d'outils avec l'ActionBar masquée.

entrez la description de l'image ici

Mais que faire si je veux quelque chose comme un thème Light avec un DarkActionBar? Puisque je dois utiliser NoActionBar, ce n'est pas une option.

Remplacer le thème de l'application

Voici où ThemeOverlay entre en jeu. Je peux spécifier le thème Dark ActionBar dans ma mise en page XML Toolbar.

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

Cela nous permet enfin d'avoir l'effet que nous voulons. Le thème Dark.ActionBar recouvre le thème de l'application Light pour cette occasion particulière.

entrez la description de l'image ici

  • Thème de l'application: Theme.AppCompat.Light.NoActionBar
  • Thème de la barre d'outils: ThemeOverlay.AppCompat.Dark.ActionBar

Si vous voulez que le menu contextuel soit léger, vous pouvez ajouter ceci:

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

Une étude plus approfondie

J'ai appris cela par l'expérimentation et en lisant les articles suivants.

Suragch
la source
Comment rendre la barre d'état transparente lors de l'utilisation de Themeoverlay?
gegobyte
Je me demande comment y parvenir avec la nouvelle MaterialToolbar
David
@David, je travaille principalement avec Flutter maintenant, donc je n'ai pas suivi les nouveaux développements Android. Si vous trouvez la réponse, n'hésitez pas à revenir ici et à laisser un commentaire, à modifier ma réponse ou à ajouter votre propre réponse.
Suragch le