Когда следует использовать Theme.AppCompat против ThemeOverlay.AppCompat?

114

Существуют следующие классы 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

и следующие классы ThemeOverlay.AppCompat:

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

Зачем, например, использовать ThemeOverlay.AppCompat.light против Theme.AppCompat.Light? Я вижу, что для ThemeOverlay определено гораздо меньше атрибутов - мне любопытно, каков предполагаемый вариант использования ThemeOverlay.

Брендан Вайнштейн
источник

Ответы:

71

Согласно этой записи блога Theme vs Style от создателя AppCompat:

[ThemeOverlays] - это специальные темы, которые накладываются на обычные темы Theme.Material, перезаписывая соответствующие атрибуты, чтобы сделать их светлыми / темными.

ThemeOverlay + ActionBar

Внимательные из вас также увидят производные от ActionBar ThemeOverlay:

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

Их следует использовать только с actionBarThemeпанелью действий с помощью нового атрибута или непосредственно на панели инструментов.

Единственное, что они в настоящее время делают иначе, чем их родители, - это то, что они меняют объект colorControlNormalto be android:textColorPrimary, тем самым делая любой текст и значки непрозрачными.

ianhanniballake
источник
155

Theme.AppCompat используется для установки глобальной темы для всего приложения. ThemeOverlay.AppCompat используется для переопределения (или «наложения») этой темы для определенных представлений, особенно для панели инструментов.

Давайте посмотрим на примере, почему это необходимо.

Темы приложений с ActionBar

ActionBar обычно отображается в приложении. Я могу выбрать его цвет, установив colorPrimaryзначение. Однако при изменении темы изменяется цвет текста на 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>

введите описание изображения здесь

Поскольку мой основной цвет - темно-синий, мне, вероятно, следует использовать одну из тем, в которой используется светлый цвет текста на панели действий, потому что черный текст трудно читать.

Скрытие ActionBar и использование панели инструментов

Весь смысл использования Theme.AppCompat, а не Theme.Material заключается в том, что мы можем разрешить более старым версиям Android использовать нашу тему дизайна материалов. Проблема в том, что более старые версии Android не поддерживают ActionBar. Таким образом документации рекомендуется скрыть ActionBar и добавить панель инструментов в ваш макет. Чтобы скрыть ActionBar, мы должны использовать одну из NoActionBarтем. На следующих изображениях показана панель инструментов со скрытой панелью действий.

введите описание изображения здесь

Но что, если мне нужно что-то вроде темы Light с DarkActionBar? Поскольку мне нужно использовать NoActionBar, это не вариант.

Переопределение темы приложения

Вот где появляется ThemeOverlay. Я могу указать тему Dark ActionBar в моем XML-макете панели инструментов.

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

Это наконец позволяет нам добиться желаемого эффекта. Тема Dark.ActionBar накладывается на тему приложения Light для этого конкретного случая.

введите описание изображения здесь

  • Тема приложения: Theme.AppCompat.Light.NoActionBar
  • Тема панели инструментов: ThemeOverlay.AppCompat.Dark.ActionBar

Если вы хотите, чтобы всплывающее меню было светлым, вы можете добавить это:

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

Дальнейшее обучение

Я узнал об этом путем экспериментов и чтения следующих статей.

Suragch
источник
Как сделать строку состояния прозрачной при использовании Themeoverlay?
gegobyte
Мне интересно, как этого добиться с помощью новой
Дэвид,
@David, сейчас я в основном работаю с Flutter, поэтому не следил за новыми разработками для Android. Если вы найдете ответ, не стесняйтесь вернуться сюда и оставить комментарий, отредактировать мой ответ или добавить свой собственный.
Suragch