Kiedy należy używać Theme.AppCompat vs ThemeOverlay.AppCompat?

114

Istnieją następujące klasy 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

i następujące klasy ThemeOverlay.AppCompat:

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

Po co na przykład używać ThemeOverlay.AppCompat.light vs Theme.AppCompat.Light? Widzę, że jest znacznie mniej zdefiniowanych atrybutów dla ThemeOverlay - jestem ciekaw, jaki jest zamierzony przypadek użycia ThemeOverlay.

Brendan Weinstein
źródło

Odpowiedzi:

71

Zgodnie z tym postem na blogu Theme vs Style autorstwa twórcy AppCompat:

[ThemeOverlays] to specjalne motywy, które nakładają się na zwykłe motywy Theme.Material, nadpisując odpowiednie atrybuty, aby były jasne / ciemne.

ThemeOverlay + ActionBar

Uważne spojrzenie z pewnością zauważyło także pochodne ActionBar ThemeOverlay:

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

Powinny być używane tylko z actionBarThemepaskiem akcji za pośrednictwem nowego atrybutu lub bezpośrednio ustawiane na pasku narzędzi Toolbar.

Jedyną rzeczą, którą obecnie robią inaczej niż ich rodzice, jest to, że zmieniają to, colorControlNormalaby być android:textColorPrimary, przez co tekst i ikony stają się nieprzezroczyste.

ianhanniballake
źródło
155

Theme.AppCompat służy do ustawiania motywu globalnego dla całej aplikacji. ThemeOverlay.AppCompat służy do zastępowania (lub „nakładania”) tego motywu dla określonych widoków, zwłaszcza paska narzędzi.

Spójrzmy na przykład, dlaczego jest to konieczne.

Motywy aplikacji z ActionBar

ActionBar jest zwykle wyświetlany w aplikacji. Mogę wybrać jego kolor, ustawiając colorPrimarywartość. Jednak zmiana motywu zmienia kolor tekstu 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>

wprowadź opis obrazu tutaj

Ponieważ moim podstawowym kolorem jest ciemnoniebieski, prawdopodobnie powinienem użyć jednego z motywów, który używa jasnego koloru tekstu na pasku akcji, ponieważ czarny tekst jest trudny do odczytania.

Ukrywanie ActionBar i używanie paska narzędzi

Cały sens używania Theme.AppCompat zamiast Theme.Material polega na tym, że możemy pozwolić starszym wersjom Androida na używanie naszego motywu Material Design. Problem polega na tym, że starsze wersje Androida nie obsługują ActionBar. Dlatego dokumentacja zaleca ukrywanie ActionBar i dodanie paska narzędzi do układu. Aby ukryć ActionBar, musimy użyć jednego z NoActionBarmotywów. Poniższe obrazy przedstawiają pasek narzędzi z ukrytym paskiem akcji.

wprowadź opis obrazu tutaj

Ale co, jeśli chcę coś takiego jak jasny motyw z DarkActionBar? Ponieważ muszę używać NoActionBar, to nie jest opcja.

Zastępowanie motywu aplikacji

Tutaj pojawia się ThemeOverlay. Mogę określić motyw Dark ActionBar w moim układzie XML paska Toolbar.

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

To wreszcie pozwala nam uzyskać pożądany efekt. Motyw Dark.ActionBar nakłada się na motyw aplikacji Light na tę szczególną okazję.

wprowadź opis obrazu tutaj

  • Motyw aplikacji: Theme.AppCompat.Light.NoActionBar
  • Motyw paska narzędzi: ThemeOverlay.AppCompat.Dark.ActionBar

Jeśli chcesz, aby menu podręczne było lekkie, możesz dodać to:

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

Dalsze badanie

Nauczyłem się tego poprzez eksperymentowanie i czytanie poniższych artykułów.

Suragch
źródło
Jak sprawić, by pasek stanu był przezroczysty podczas korzystania z Themeoverlay?
gegobyte
Zastanawiam się, jak to osiągnąć dzięki nowemu MaterialToolbar
David
@David, obecnie pracuję głównie z Flutter, więc nie na bieżąco z nowościami w Androidzie. Jeśli znajdziesz odpowiedź, wróć tutaj i zostaw komentarz, edytuj moją odpowiedź lub dodaj własną odpowiedź.
Suragch