Quando se deve usar Theme.AppCompat vs ThemeOverlay.AppCompat?

114

Existem as seguintes classes 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

e as seguintes classes ThemeOverlay.AppCompat:

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

Por que alguém usaria ThemeOverlay.AppCompat.light versus Theme.AppCompat.Light, por exemplo? Vejo que há muito menos atributos definidos para ThemeOverlay - estou curioso para saber qual é o caso de uso pretendido para ThemeOverlay.

Brendan Weinstein
fonte

Respostas:

71

De acordo com esta postagem do blog Theme vs Style do criador do AppCompat:

[ThemeOverlays] são temas especiais que se sobrepõem aos temas normais de Theme.Material, substituindo os atributos relevantes para torná-los claros / escuros.

ThemeOverlay + ActionBar

Os olhos mais atentos de vocês também verão os derivados ActionBar ThemeOverlay:

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

Eles só devem ser usados ​​com a Barra de ação por meio do novo actionBarThemeatributo ou configurados diretamente na barra de ferramentas.

A única coisa que eles fazem atualmente de maneira diferente para seus pais é que eles mudam o colorControlNormalser android:textColorPrimary, tornando qualquer texto e ícone opaco.

ianhanniballake
fonte
155

Theme.AppCompat é usado para definir o tema global para todo o aplicativo. ThemeOverlay.AppCompat é usado para substituir (ou "sobrepor") esse tema para visualizações específicas, especialmente a barra de ferramentas.

Vejamos um exemplo de por que isso é necessário.

Temas de aplicativos com uma ActionBar

O ActionBar normalmente é mostrado em um aplicativo. Posso escolher sua cor definindo o colorPrimaryvalor. No entanto, alterar o tema altera a cor do texto na 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>

insira a descrição da imagem aqui

Como minha cor primária é azul escuro, provavelmente devo usar um dos temas que usa uma cor de texto clara na barra de ação porque o texto em preto é difícil de ler.

Escondendo a ActionBar e usando uma barra de ferramentas

O objetivo de usar Theme.AppCompat em vez de Theme.Material é permitir que versões mais antigas do Android usem nosso tema de design de material. O problema é que as versões mais antigas do Android não suportam o ActionBar. Assim, a documentação recomenda ocultar a ActionBar e adicionar uma barra de ferramentas ao seu layout. Para ocultar a ActionBar, temos que usar um dos NoActionBartemas. As imagens a seguir mostram a barra de ferramentas com a ActionBar oculta.

insira a descrição da imagem aqui

Mas e se eu quiser algo como um tema Light com uma DarkActionBar? Já que tenho que usar NoActionBar, isso não é uma opção.

Substituindo o tema do aplicativo

É aqui que entra o ThemeOverlay. Posso especificar o tema Dark ActionBar no layout xml da barra de ferramentas.

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

Isso finalmente nos permite ter o efeito que desejamos. O tema Dark.ActionBar se sobrepõe ao tema do aplicativo Light para esta ocasião específica.

insira a descrição da imagem aqui

  • Tema do aplicativo: Theme.AppCompat.Light.NoActionBar
  • Tema da barra de ferramentas: ThemeOverlay.AppCompat.Dark.ActionBar

Se você quiser que o menu pop-up seja leve, você pode adicionar isto:

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

Um estudo mais aprofundado

Aprendi isso por meio de experiências e lendo os artigos a seguir.

Suragch
fonte
Como tornar a barra de status transparente ao usar Themeoverlay?
gegobyte
Estou me perguntando como conseguir isso com o novo MaterialToolbar
David
@David, estou trabalhando principalmente com o Flutter agora, então não acompanhei os novos desenvolvimentos do Android. Se você encontrar a resposta, fique à vontade para voltar aqui e deixar um comentário, editar minha resposta ou adicionar sua própria resposta.
Suragch