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

Существуют следующие классы 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 vs Theme.AppCompat.Light, например? Я вижу, что для ThemeOverlay существует гораздо меньше атрибутов - мне любопытно, что предназначен для использования в ThemeOverlay.

Ответ 1

За это Тема против сообщения в блоге стиля создателем AppCompat:

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

ThemeOverlay + ActionBar

Острый взгляд на вас также увидит производные ActionBar ThemeOverlay:

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

Они должны использоваться только с панелью действий через новый атрибут actionBarTheme или непосредственно устанавливаться на панели инструментов.

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

Ответ 2

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. Следующие изображения показывают панель инструментов с скрытым ActionBar.

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

Но что, если я хочу что-то вроде темы 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"

Дальнейшее исследование

Я узнал об этом через эксперименты и прочитал следующие статьи.