¿Cuándo debería uno usar Theme.AppCompat vs ThemeOverlay.AppCompat?

Existen las siguientes clases de 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 de ThemeOverlay.AppCompat:

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

¿Por qué uno usaría ThemeOverlay.AppCompat.light versus 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.

Según esta publicación de blog Tema por estilo, realizada por el creador de AppCompat:

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

ThemeOverlay + ActionBar

Tus ojos entusiastas también habrán visto los derivados de ActionBar ThemeOverlay:

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

Estos solo se deben usar con la barra de acciones a través del nuevo atributo actionBarTheme , o directamente en su barra de herramientas.

Las únicas cosas que actualmente hacen de forma diferente a sus padres es que cambian el colorControlNormal a ser android:textColorPrimary , lo que hace que el texto y los icons sean opacos.

Theme.AppCompat se utiliza para establecer el tema global para 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 la aplicación con una ActionBar

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

  

enter image description here

Como mi color primario es azul oscuro, probablemente debería usar uno de los temas que usa un color de texto claro en la barra de acciones porque el texto negro es difícil de leer.

Ocultar el ActionBar y usar una barra de herramientas

El objective de usar Theme.AppCompat en lugar de Theme.Material es que podemos permitir que versiones anteriores de Android utilicen 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 ActionBar, debemos usar uno de los temas de NoActionBar . Las siguientes imágenes muestran la barra de herramientas con la barra de acciones oculta.

enter image description here

Pero, ¿y si quiero algo como un tema de Luz con una DarkActionBar? Como tengo que usar NoActionBar, esa no es una opción.

Anulando el tema de la aplicación

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

  

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

enter image description here

  • 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 la lectura de los siguientes artículos.

  • Configurar la barra de la aplicación
  • Utilice android: theme y ThemeOverlay para vistas específicas del tema y sus descendientes
  • Theming con AppCompat
  • Use colorPrimary para colorear su barra de aplicaciones
  • Tema vs Estilo