¿Cuándo se debe usar Theme.AppCompat vs ThemeOverlay.AppCompat?

113

Existen las siguientes clases Theme.AppCompat:

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

y las siguientes clases ThemeOverlay.AppCompat:

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

¿Por qué se usaría ThemeOverlay.AppCompat.light vs Theme.AppCompat.Light, por ejemplo? Veo que hay muchos menos atributos definidos para ThemeOverlay; tengo curiosidad por saber cuál es el caso de uso previsto para ThemeOverlay.

Brendan Weinstein
fuente

Respuestas:

71

Según esta publicación de blog Theme vs Style del creador de AppCompat:

[ThemeOverlays] son ​​temas especiales que se superponen a los temas normales de Theme.Material, sobrescribiendo los atributos relevantes para hacerlos claros / oscuros.

ThemeOverlay + ActionBar

Los más entusiastas de ustedes también habrán visto los derivados de ActionBar ThemeOverlay:

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

Estos solo deben usarse con la barra de acción a través del nuevo actionBarThemeatributo, o configurarse directamente en su barra de herramientas.

Lo único que estos hacen actualmente de manera diferente a sus padres es que cambian el colorControlNormalaspecto android:textColorPrimary, haciendo que el texto y los íconos sean opacos.

Ianhanniballake
fuente
155

Theme.AppCompat se utiliza para establecer el tema global de toda la aplicación. ThemeOverlay.AppCompat se utiliza para anular (o "superponer") ese tema para vistas específicas, especialmente la barra de herramientas.

Veamos un ejemplo de por qué esto es necesario.

Temas de aplicaciones con ActionBar

La ActionBar normalmente se muestra en una aplicación. Puedo elegir su color estableciendo el colorPrimaryvalor. Sin embargo, cambiar el tema cambia el color del texto en la barra de acciones.

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

ingrese la descripción de la imagen aquí

Dado que mi color principal es el azul oscuro, probablemente debería usar uno de los temas que usa un color de texto claro en la barra de acción porque el texto negro es difícil de leer.

Ocultar la barra de acciones y usar una barra de herramientas

El objetivo de usar Theme.AppCompat en lugar de Theme.Material es que podamos permitir que las versiones anteriores de Android usen nuestro tema de diseño de materiales. El problema es que las versiones anteriores de Android no son compatibles con ActionBar. Por lo tanto, la documentación recomienda ocultar la barra de acciones y agregar una barra de herramientas a su diseño. Para ocultar la ActionBar tenemos que usar uno de los NoActionBartemas. Las siguientes imágenes muestran la barra de herramientas con la barra de acciones oculta.

ingrese la descripción de la imagen aquí

Pero, ¿qué pasa si quiero algo como un tema claro con DarkActionBar? Como tengo que usar NoActionBar, esa no es una opción.

Anulación del tema de la aplicación

Aquí es donde entra ThemeOverlay. Puedo especificar el tema Dark ActionBar en mi diseño xml de la barra de herramientas.

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

Esto finalmente nos permite tener el efecto que queremos. El tema Dark.ActionBar se superpone al tema de la aplicación Light para esta ocasión en particular.

ingrese la descripción de la imagen aquí

  • Tema de la aplicación: Theme.AppCompat.Light.NoActionBar
  • Tema de la barra de herramientas: ThemeOverlay.AppCompat.Dark.ActionBar

Si desea que el menú emergente sea ligero, puede agregar esto:

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

Estudio adicional

Aprendí esto a través de la experimentación y leyendo los siguientes artículos.

Suragch
fuente
¿Cómo hacer que la barra de estado sea transparente cuando se usa Themeoverlay?
gegobyte
Me pregunto cómo lograr esto con el nuevo MaterialToolbar
David
@David, ahora estoy trabajando principalmente con Flutter, así que no me he mantenido al día con los nuevos desarrollos de Android. Si encuentra la respuesta, no dude en volver aquí y dejar un comentario, editar mi respuesta o agregar su propia respuesta.
Suragch