Appcompat что такое android

Обновлено: 30.09.2022

Для разработки приложений Xamarin.Forms для Android требуется Visual Studio. На странице поддерживаемых платформ содержится дополнительная информация о предварительных требованиях.

Специфика платформы

Зависимость от платформы позволяет вам использовать функции, доступные только на определенной платформе, без реализации пользовательских средств визуализации или эффектов.

Для представлений, страниц и макетов Xamarin.Forms на Android доступны следующие функции для конкретных платформ:

  • Управление Z-порядком визуальных элементов для определения порядка прорисовки. Дополнительные сведения см. в разделе VisualElement Elevation для Android.
  • Отключение устаревшего цветового режима в поддерживаемом VisualElement . Дополнительную информацию см. в разделе Цветовой режим VisualElement Legacy для Android.

Для представлений Xamarin.Forms на Android предусмотрены следующие зависящие от платформы функции:

  • Использование значений заполнения и тени по умолчанию для кнопок Android. Дополнительную информацию см. в разделе Отступы и тени кнопок на Android.
  • Настройка параметров редактора метода ввода для программной клавиатуры для элемента Entry . Дополнительную информацию см. в разделе Параметры редактора методов ввода для Android.
  • Включение тени для ImageButton . Дополнительные сведения см. в статье «Тени ImageButton на Android».
  • Включение быстрой прокрутки в ListView . Дополнительную информацию см. в разделе Быстрая прокрутка ListView на Android.
  • Управление переходом, используемым при открытии SwipeView. Дополнительную информацию см. в разделе Режим перехода SwipeView Swipe.
  • Управление тем, может ли WebView отображать смешанный контент. Дополнительную информацию см. в разделе Смешанное содержимое WebView на Android.
  • Включение масштабирования в WebView . Дополнительную информацию см. в разделе WebView Zoom для Android.

Для ячеек Xamarin.Forms на Android предусмотрены следующие зависящие от платформы функции:

  • Включение устаревшего режима контекстных действий ViewCell, чтобы меню контекстных действий не обновлялось при изменении выбранного элемента в ListView. Дополнительную информацию см. в разделе Контекстные действия ViewCell на Android.

Для страниц Xamarin.Forms на Android предусмотрены следующие зависящие от платформы функции:

  • Установка высоты панели навигации на NavigationPage . Дополнительную информацию см. в разделе Высота панели NavigationPage на Android.
  • Отключение анимации перехода при навигации по страницам в TabbedPage . Дополнительную информацию см. в разделе Анимация перехода между страницами TabbedPage на Android.
  • Включение пролистывания страниц в TabbedPage . Дополнительную информацию см. в статье Перелистывание страниц TabbedPage на Android.
  • Установка расположения и цвета панели инструментов на TabbedPage . Дополнительную информацию см. в разделе Размещение и цвет панели инструментов TabbedPage на Android.

Для класса приложения Xamarin.Forms на Android предусмотрены следующие зависящие от платформы функции:

  • Настройка режима работы программной клавиатуры. Дополнительные сведения см. в разделе Режим ввода с программной клавиатуры на Android.
  • Отключение событий жизненного цикла страницы «Исчезновение» и «Появление» при паузе и возобновлении соответственно для приложений, использующих AppCompat. Дополнительную информацию см. в разделе События жизненного цикла страницы на Android.

Поддержка платформы

Изначально проект Android Xamarin.Forms по умолчанию использовал старый стиль отрисовки элемента управления, который был распространен до Android 5.0. Приложения, созданные с использованием шаблона, имеют FormsApplicationActivity в качестве базового класса своей основной активности.

Материальный дизайн через AppCompat

Проекты Android Xamarin.Forms теперь используют FormsAppCompatActivity в качестве базового класса своей основной активности. Этот класс использует функции AppCompat, предоставляемые Android, для реализации тем Material Design.

Вот пример Todo с FormsApplicationActivity по умолчанию:

Пример приложения Todo без AppCompat

А это тот же код после обновления проекта для использования FormsAppCompatActivity (и добавления дополнительной информации о теме):

Пример приложения Todo с AppCompat и Theming

При использовании FormsAppCompatActivity базовые классы для некоторых пользовательских средств визуализации Android будут другими.

Вы в трех шагах от того, чтобы добавить в свое Android-приложение отличную встроенную поддержку.

Видео об интеграции

Получите последнюю стабильную версию Helpshift SDK для Android

Zip-файл содержит Helpshift SDK в формате Android Library Project.

Добавление последней стабильной версии SDK в ваш проект

Начиная с версии 2.8.x SDK реализует пользовательский интерфейс панели действий и зависит от библиотеки appcompat v7

Чтобы добавить Helpshift SDK в проект Android-приложения, просто разархивируйте загруженный zip-файл и импортируйте его в Eclipse:

  1. Выберите Файл > Импорт
  2. Выберите Android > Существующий код Android в рабочую область и нажмите Далее.

Нажмите Обзор для корневого каталога и выберите путь к helpshift-android-sdk > Готово.

Импорт SDK Helpshift в Eclipse

Также установите флаг manifestmerger.enabled в значение true в файле project.properties:

Пакет SDK Helpshift зависит от библиотеки appcompat версии 7 для реализации пользовательского интерфейса панели действий. Итак, импортируйте библиотеку appcompat v7 в Eclipse:

  1. Выберите Файл > Импорт
  2. Выберите Android > Существующий код Android в рабочую область и нажмите Далее.

Нажмите Обзор для корневого каталога и выберите путь к библиотеке appcompat v7 > Готово.

Импорт совместимости приложений v7 в Eclipse

Добавить ссылку на библиотеку appcompat v7 в Helpshift SDK:

В проводнике пакетов щелкните правой кнопкой мыши проект Helpshift SDK и выберите Свойства.

Package Explorer

В окне "Свойства" выберите группу свойств "Android" слева и найдите свойства библиотеки справа.

Выберите /path/to/appcompat/ и нажмите Удалить.

Удаление пути/к/appcompat/

Нажмите Добавить, чтобы открыть диалоговое окно выбора проекта. В списке доступных проектов библиотеки выберите библиотеку appcompat v7 и нажмите ОК.

Выбор проекта

Нажмите Применить и ОК в окне свойств.

Добавление ссылки на библиотеку appcompat v7< бр />

Добавьте ссылку на Helpshift SDK в свой проект:

  1. В проводнике пакетов щелкните проект правой кнопкой мыши и выберите Свойства.
  2. В окне "Свойства" выберите группу свойств "Android" слева и найдите свойства библиотеки справа.
  3. Нажмите Добавить, чтобы открыть диалоговое окно выбора проекта. В списке доступных проектов библиотеки выберите Helpshift SDK и нажмите ОК.

Нажмите Применить и ОК в окне свойств.

Добавление ссылки на Helpshift SDK

Дополнительная конфигурация

Пакет SDK Helpshift может наследовать стили тем из существующих файлов тем панели действий через. переменная helpshift.res.parent. Подробнее об этом читайте в разделе Дизайн

В файле build.xml вставьте следующее между тегами. Это проверит XML-файлы Helpshift на наличие необходимых ресурсов и предупредит вас, если какой-либо из этих ресурсов отсутствует. Если цель «-post-compile» отсутствует, оберните приведенный ниже фрагмент кода расширением . теги.

Если вы используете Proguard, вам необходимо добавить следующее в файл проекта proguard-project.txt.

Helpshift Android SDK версии 2.8.2 и более поздних версий не подвергается предварительной обфускации с помощью Proguard. Чтобы сжать и запутать Helpshift SDK, мы рекомендуем вам использовать эту конфигурацию Proguard в вашем проекте.

Proguard рекомендуется для сокращения, оптимизации и запутывания вашего кода путем удаления неиспользуемого кода и переименования классов, полей и методов с семантически скрытыми именами. В результате получается APK-файл меньшего размера, который сложнее реконструировать. Для получения дополнительной информации см. документацию Proguard

Поддержка Maven

Для использования Helpshift SDK через. Maven добавляет к вашему тегу следующую зависимость:

Вам также необходимо убедиться, что в ваш тег добавлены зависимости для библиотеки appcompat версии 7. Вы можете использовать Maven Android SDK Deployer для установки необходимых библиотек из локальной установки Android SDK. Чтобы установить необходимые библиотеки поддержки, запустите mvn install -P 4.3 из папки maven-android-sdk-deployer.

Совместимость ActionBarSherlock

Android SDK версии 2.8 не имеет обратной совместимости с ActionBarSherlock (ABS). При выпуске официальной панели действий Google мы отказались от использования ABS, разработанной Джейком Уортоном

Панель действий Google зависит от новой библиотеки appcompat v7

Если вы не готовы к переходу, вы можете загрузить и использовать Android SDK версии 2.7.1 — последний SDK, совместимый с ActionBarSherlock

Причины, по которым рекомендуется использовать appcompat, а не ActionBarSherlock

  • Можно обновлять по мере развития API панели действий.
  • Встроенная поддержка наследственной навигации.
  • Использование базовых классов Menu и MenuItem.
  • Продолжайте использовать класс Fragment библиотеки поддержки.
  • Встроенная поддержка ActionBarDrawerToggle для использования с DrawerLayout.
  • Бэкпорт PopupMenu.

Для получения дополнительной информации см. ActionBarCompat и источник приложения I/O 2013

Сегодня большинство недавно написанных Activity расширяют AppCompatActivity. Тот факт, что он добавляет обратную совместимость, значительно облегчил жизнь нам, разработчикам Android. Тем не менее, как это работает? В частности, как он заменяет TextView в макете xml на AppCompatTextView? Этот пост посвящен одному из аспектов AppCompatActivity — просмотру инфляции.

Фабрика2

В Android мы часто пишем наши макеты в XML-файлах. Они связаны с нашим приложением (преобразованы в двоичный XML для повышения производительности с помощью aapt/2), а затем увеличиваются во время выполнения с помощью LayoutInflater .

В LayoutInflater есть два аккуратных маленьких метода, которые называются setFactory и setFactory2. В документации к этому методу говорится:

Прикрепите пользовательский интерфейс Factory для создания представлений при использовании этого LayoutInflater. Это значение не должно быть нулевым и может быть установлено только один раз; после настройки нельзя сменить заводскую. Это вызывается для каждого имени элемента при анализе xml. Если фабрика возвращает представление, оно добавляется в иерархию. Если он возвращает значение null, вызывается следующий заводской метод onCreateView(View, String, AttributeSet) по умолчанию.

Обратите внимание, что Factory2 реализует Factory , поэтому для любых приложений API 11+ следует использовать setFactory2. По сути, это дает нам возможность перехватить создание каждого тега (элемента представления) в xml. Давайте посмотрим на это на практике:

Здесь мы просто устанавливаем Factory2 в LayoutInflater для этого контекста. Всякий раз, когда мы находим TextView , мы заменяем его нашим собственным подклассом.

RedTextView — это просто подкласс TextView с дополнительным вызовом setBackgroundColor для установки красного фона в конце каждого конструктора:

В этом случае factory.xml выглядит следующим образом:

Когда мы запустим это и воспользуемся Инспектором макетов Android Studio, мы обнаружим, что все наши объекты TextView теперь являются объектами RedTextView — круто!

AppCompatActivity и Factory2

Если мы просто изменим приведенную выше FactoryActivity, чтобы вместо этого расширить AppCompatActivity, мы увидим, что наши TextView действительно являются RedTextView , но добавленная нами Button остается Button, а не становится AppCompatButton. Почему?

getDelegate() возвращает правильный делегат в зависимости от версии API ( AppCompatDelegateImplV14 , AppCompatDelegateImplV23 , AppCompatDelegateImplN и т. д.). Следующий метод устанавливает фабрику представлений — этот код вызывает setFactory2, когда layoutInflater.getFactory возвращает значение null — иначе он ничего не делает.

Тот факт, что наша кнопка теперь не меняется, имеет смысл, поскольку AppCompatActivity не устанавливает свою фабрику, если она уже установлена.

Обратите внимание, что setFactory2 в FactoryActivity находится перед super.onCreate. Если это не так, setFactory2 выдаст исключение, когда родителем является AppCompatActivity , поскольку он устанавливает свой собственный Factory2 , и, как говорится в документации, «Это не должно быть null и может быть установлен только один раз; после настройки вы не можете изменить заводские настройки.»

Хорошая игра с Factory2 AppCompatActivity

Что делать, если я хочу иметь свой собственный Factory2 , но также хочу, чтобы AppCompatActivity запускал свой Factory ? Давайте рассмотрим несколько способов сделать это.

Делегирование AppCompatDelegate

Внутри AppCompatDelegate мы видим метод createView (не путать с onCreateView, реализующим Factory и Factory2):

С этой информацией мы можем просто изменить наш вызов setFactory2, чтобы делегировать его в AppCompatDelegate, когда мы не хотим его обрабатывать:

Запустив это, мы действительно видим, что наши объекты TextView стали объектами RedTextView, а наша кнопка стала объектом AppCompatButton — успех!

Переопределение viewInflaterClass

Если мы посмотрим на createView из AppCompatDelegate , мы увидим код, который создает экземпляр AppCompatViewInflater с использованием отражения, если он еще не установлен. Конкретный класс, который он создает, происходит из R.styleable.AppCompatTheme_viewInflaterClass , для которого по умолчанию установлено значение AppCompatViewInflater.

Установив тему для FactoryActivity примерно так:

Мы можем сделать так, чтобы AppCompatDelegate использовал наш подкласс AppCompatViewInflater:

Проект Google Material Design Components фактически использует этот подход, чтобы переопределить создание каждой кнопки с помощью соответствующего MaterialButton, который является подклассом AppCompatButton , как можно увидеть здесь.

Этот подход очень эффективен, так как он позволяет приложению, которое использует библиотеку, такую ​​​​как компоненты дизайна материалов, получать оттенки и кнопки дизайна материалов, ничего не делая, кроме установки правильной темы.

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

Пользовательский LayoutInflater

Третий способ сделать это — использовать собственный LayoutInflater, который всегда возвращается при вызове getSystemService через ContextThemeWrapper (устанавливается путем перезаписи attachBaseContext в Activity ). Затем этот настраиваемый LayoutInflater может оборачивать вызовы метода setFactory2 для вызова базового Factory2 и для вызова собственной логики до или после. Этот метод используется библиотекой ViewPump (отсюда я и узнал о нем).

Детали реализации

В этом разделе рассматриваются некоторые мельчайшие подробности реализации AppCompatDelegate способа представления инфляции (поскольку я нашел это довольно интересным и узнал несколько вещей по пути сюда).

при создании представления

Мы ожидаем, что метод onCreateView в Factory2 просто вызовет непосредственно createView (упомянутый выше в разделе Делегирование AppCompatDelegate). На самом деле так оно и есть, но если посмотреть на код, то там есть лишняя деталь — вызов callActivityOnCreateView. В AppCompatDelegateImplV14 это выглядит так:

Глядя на исходный код LayoutInflater, мы видим, что часть createViewFromTag пытается получить представление от фабрики и, не найдя его, возвращается к mPrivateFactory и, наконец, возвращается к попытке создать класс, который тег относится к. mPrivateFactory задается Activity в его конструкторе. (Интересно, что именно этот mPrivateFactory отвечает за раздувание фрагментов, как показано здесь).

В Gingerbread через Honeycomb LayoutInflater не имеет понятия mPrivateFactory, чтобы позволить Activity запускать собственную резервную логику для создания представлений. Следовательно, callActivityOnCreateView вызывает этот метод, чтобы позволить этому коду выполняться в старых API. Сейчас это в основном не имеет значения, так как AppCompat в любом случае теперь 14+, но интересная вещь, которую я узнал из этого, касается Window.Callback.

Window.Callback – это API от окна к вызывающему объекту. Это позволяет клиенту перехватывать диспетчеризацию клавиш, панели и меню и т. д. Он обернут AppCompatActivity, чтобы позволить ему обрабатывать определенные события, такие как нажатие клавиши (для обработки нажатия кнопок меню и возврата) среди прочего.< /p>

создать представление

На высоком уровне createView в AppCompatDelegateImplV9 выполняет две функции: во-первых, он автоматически создает AppCompatViewInflater или соответствующий подкласс, читая из темы, как указано в разделе Переопределение viewInflaterClass выше. Во-вторых, он запрашивает инфлятор для создания представления.

createView в AppCompatViewInflater вычисляет правильный контекст (принимая во внимание app:theme и android:theme по мере необходимости, а также оборачивая контекст для подкрашивания по мере необходимости), а затем создает правильный виджет AppCompat, в зависимости от имени, переданного в (т. е. если это TextView , вызовите createTextView, который возвращает AppCompatTextview и т. д.).

Поддерживающее приложение:тема

В Lollipop и более поздних версиях приложение app:theme можно применить к представлению, чтобы переопределить тему для этого конкретного представления и его дочерних элементов. AppCompat воспроизводит это поведение до API 21, наследуя контекст родительского представления (при условии, что это родительское представление не является корневым представлением расширяемого макета).

Прежде чем AppCompat попытается расширить представление, он получает родительский контекст (при условии, что он должен наследовать его, как указано выше), а затем пытается создать тематический контекст, содержащий android:theme, если это предварительно Lollipop (поскольку Lollipop обрабатывает android:theme автоматически) и app:theme в противном случае. Это гарантирует, что виджет наполняется правильным контекстом .

Кроме того, AppCompat также будет обертывать контекст с помощью TintContextWrapper pre-Lollipop (api 21), если разработчик явным образом попросил разрешить использование векторов appcompat из ресурсов (чтобы разрешить использование векторов в таких вещах, как android:src ) с помощью отключенного по умолчанию вызова setCompatVectorFromResourcesEnabled в AppCompatDelegate .

Создание представления и резервных вариантов

Учитывая эту информацию, код готов определить, какое представление создать — он просматривает список поддерживаемых виджетов в операторе switch, обрабатывая распространенные представления, такие как TextView , ImageView и т. д., создавая их подклассы AppCompat.Если представление неизвестного типа, оно вызывает createView с правильным контекстом (этот метод по умолчанию возвращает null, но может быть перезаписан подклассом AppCompatViewInflater).

Если в этот момент представление по-прежнему пусто, выполняется проверка, чтобы убедиться, что исходный контекст представления отличается от контекста его родителя. Это происходит, когда android:theme в дочернем элементе отличается от родительского. Чтобы воспроизвести поведение Lollipop и позволить дочерним элементам наследовать родительскую тему, AppCompat в этих случаях пытается рефлексивно создать представление с правильным контекстом.

После некоторого кода для исправления поведения android:onClick для ContextWrapper возвращается представление. Если это представление по-прежнему равно null , LayoutInflater попытается увеличить его, создав базовое представление.

Обзор и варианты использования

Подводя итог, AppCompatActivity устанавливает Factory2 в LayoutInflater для перехвата создания представления для обеспечения обратной совместимости (добавление поддержки тонирования виджетов, обработка android:theme и т. д.). Он также позволяет расширять это, поэтому разработчик также может настраивать здесь обработку.

За пределами AppCompat этот трюк использовался для выполнения многих интересных задач — среди первых, которые я увидел, были те, которые были реализованы библиотекой Probe (теперь устаревшей). Используя комбинацию Factory2 и подключаемого модуля Gradle, разработчик может легко включить OvermeasureInterceptor для определения дополнительных проходов измерения или LayoutBoundsInterceptor для выделения границ представления.

Библиотека Calligraphy использует этот трюк, чтобы упростить добавление шрифтов в TextView s. Он использует библиотеку ViewPump (упомянутую ранее), которая также перечисляет некоторые потенциальные варианты использования на своей вики рецептов.

Наконец, проект Google Material Components для Android устанавливает собственный AppCompatViewInflater для замены Button на MaterialButton s.

Мне нравятся стандартные компоненты — основные строительные блоки, обеспечивающие общую функциональность и доступность. Мне даже больше нравятся стандартные компоненты с единообразным дизайном — это то, что AppCompat предоставляет из коробки. Но что мне нравится больше всего? Стандартные компоненты, которые неизменно выглядят потрясающе и придают индивидуальность моим приложениям. Это то, что вы получаете, когда используете темы, предоставляемые AppCompat.

Теперь вы сможете добавить в свою тему всего несколько цветов, таких как colorPrimary, colorPrimaryDark и colorAccent, и вы сможете влиять на большие части вашего приложения без индивидуальной настройки компонентов.

Что касается тематики, то в Lollipop произошел большой сдвиг с появлением материального дизайна. Больше не ожидалось, что каждая кнопка будет либо точно такой же, либо полностью настраиваемой. Инструменты для создания цветных компонентов или настраиваемых цветных панелей действий превратились из необходимых в больше, чем вам действительно нужно. Вместо этого вы можете настроить цветовую палитру своей темы, чтобы автоматически раскрасить большую часть вашего приложения. Мощный материал.

Но не должны ли быть только Lollipop и выше, чтобы получить крутые вещи, верно? Таким образом, большое внимание в AppCompat v21 было уделено переносу этой новой темы на все устройства API 7+, и с тех пор поддержка только росла (что связано с тем, что виджеты с поддержкой оттенка стали общедоступными в AppCompat 22.1, а в AppCompat 23.1 добавлено еще больше функций). Это означает, что простая тема может выглядеть так:

Очень отличается от того, что вы могли видеть до Lollipop (к счастью!).

Первый цвет, который вам нужно добавить, это colorPrimary. Этот цвет должен представлять ваш основной фирменный цвет, который пользователи должны ассоциировать с вашим приложением (отсюда и его «основное» название). И, очевидно, первое, что нужно раскрасить с помощью colorPrimary, — это панель приложения.


При использовании базовой темы Theme.AppCompat и панели приложений, предоставленной AppCompat, вы обнаружите, что фон панели приложений автоматически использует ваш colorPrimary. Однако если вы используете Панель инструментов (наряду с темой Theme.AppCompat.NoActionBar, скорее всего), вам потребуется вручную установить цвет фона.< /p>

Как упоминалось в нашем предыдущем совете по раскрашиванию панели приложений, формат ?attr/ — это то, как вы сообщаете Android, что это значение должно быть разрешено из вашей темы, а не напрямую из ресурса. Как правило, при выборе colorPrimary рассмотрите цвета из цветовой палитры материала со значением около 500.

Как и следовало ожидать из названия, colorPrimaryDark — это более темный вариант вашего основного цвета, который используется в качестве цвета фона строки состояния, украшающей верхнюю часть экрана. Эта разница в цвете дает пользователям четкое разделение между строкой состояния, управляемой системой, и вашим приложением. По сравнению с colorPrimary это должен быть цвет 700 из цветовой палитры того же оттенка.

Несмотря на то, что AppCompat может выполнять резервное копирование многих вещей, правильная окраска строки состояния зависит от новых API, представленных в Lollipop (а именно, windowDrawsSystemBarBackgrounds), поэтому не ожидайте увидеть colorPrimaryDark строка состояния на старых версиях платформы.

Там, где colorPrimary и colorPrimaryDark больше подходят в качестве цвета фона для разделов пользовательского интерфейса, в подавляющем большинстве случаев вы увидите colorAccent в небольших количествах, которые обеспечивают контрастный цвет, чтобы привлечь внимание к определенным компонентам.

На самом деле многие встроенные компоненты уже используют colorAccent:

  • Отмеченные флажки
  • Радиокнопки
  • Подчеркивание в фокусе
  • EditText и индикатор текущей вкладки плавающей метки курсора
  • Выбранный элемент NavigationView
  • Фон ​​для FloatingActionButton

Хотя вы можете заметить еще несколько приложений, ориентированных на colorPrimary и colorPrimaryDark (в конце концов, они являются основными), colorAccent может быть простой способ привлечь внимание пользователя, предоставить контекст и вызвать доверие (все важные вещи, если вы посмотрите на исследования пользователей!).

Если этих трех основных цветов недостаточно, вам пока не нужно прибегать к окрашиванию определенных компонентов: в цветовой палитре есть еще несколько цветов, которые могут помочь вам настроить определенные вещи:

  • colorControlNormal управляет «нормальным» состоянием компонентов, таких как невыбранный EditText и невыбранные флажки и радиокнопки.
  • colorControlActivated переопределяет colorAccent в качестве активированного или отмеченного состояния для флажков и радиокнопок
  • colorControlHighlight управляет цветом ряби.

Приведенный выше пример темы имел родительскую тему Theme.AppCompat. Если вы когда-либо смотрели на исходный код базовой темы, вы увидите, что тема устанавливает почти все возможное, как и следовало ожидать от темы Activity. Однако Lollipop и AppCompat начиная с версии 22.1 позволяют применять темы к отдельным представлениям.

Как упоминалось в нашем предыдущем совете, ThemeOverlay — это отдельный тип родительской темы, который изменяет только то, что необходимо, например ThemeOverlay.AppCompat.Light изменяет цвета фона, цвета текста, и выделяет цвета, как если бы это была светлая тема, а ThemeOverlay.AppCompat.Dark делает то же самое для переключения на темную тему.

Это особенно распространено, когда дело доходит до панели инструментов, поэтому существуют отдельные ThemeOverlay.AppCompat.ActionBar и ThemeOverlay.AppCompat.Dark.ActionBar, которые также измените colorControlNormal на android:textColorPrimary и задайте правильный стиль SearchView, как ожидается для этих компонентов:

Конечно, реальная сила здесь заключается в создании собственной темы ThemeOverlay, которая делается так же, как и любая другая тема — просто убедитесь, что вы используете вариант ThemeOverlay.AppCompat в качестве родительской темы:

Поскольку родительские темы ThemeOverlay.AppCompat автоматически преобразуют AppCompat colorPrimary в атрибуты android:colorPrimary платформы Lollipop+ — вы вы обнаружите, что все не совсем так, как вы ожидаете, если вы опустите родительскую тему!

Поэтому независимо от того, есть ли у вас команда дизайнеров, один дизайнер или вы работаете над дизайном своего приложения самостоятельно, использование доступных вам цветов тем является важным первым шагом и гарантирует, что вы получите максимальную отдачу от стандартных компонентов без прибегая к приложению в основном разных оттенков серого.

Присоединяйтесь к обсуждению в записи Google+ и следите за коллекцией шаблонов разработки для Android, чтобы узнать больше!

Читайте также: