1. Прежде чем начать
В этом практическом занятии вы обновите стартовое приложение — калькулятор чаевых — чтобы использовать новые функции Material Design 3, позволяющие динамически изменять пользовательский интерфейс приложения в зависимости от обоев пользователя. Ниже представлены несколько скриншотов приложения с применением динамической смены цветов. Вы также рассмотрите несколько дополнительных сценариев, позволяющих управлять применением цветов.
Предварительные требования
Разработчики должны быть
- Знание основных концепций оформления тем в Android.
- Уверенно владеет навыками изменения темы оформления приложения.
Что вы узнаете
- Как отличить существующие компоненты Material от тем Material 3
- Как обновить тему до Material 3
- Как создавать темы оформления с помощью наших инструментов и применять их.
- Как атрибуты темы соотносятся друг с другом
Что вам понадобится
- Компьютер с установленной программой Android Studio.
- Код приложения Tip Time. https://github.com/google-developer-training/android-basics-kotlin-tip-calculator-app-solution
2. Обзор стартового приложения
Приложение Tip Time — это калькулятор чаевых с возможностью настройки размера чаевых. Это одно из примеров приложений из нашего учебного курса «Основы Android на Kotlin».

3. Обновление зависимостей Gradle
Прежде чем обновлять саму тему и применять динамический цвет, необходимо внести несколько изменений в файл build.gradle вашего приложения.
В разделе зависимостей убедитесь, что библиотека материалов имеет версию 1.5.0-alpha04 или более позднюю:
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
}
В разделе Android измените значения compileSdkVersion и targetSdkVersion.
до 31 года или позже:
android {
compileSdkVersion 31
// ...
defaultConfig {
// ...
targetSdkVersion 31
}
}
Эти инструкции предполагают использование в приложении относительно новых зависимостей. Для приложений, которые еще не используют Material Design или используют более новую версию, пожалуйста, ознакомьтесь с инструкциями в документации «Начало работы» по компонентам Material Design для Android .
Везде, где вы создали свои темы, измените ссылки с Theme.MaterialComponents.* на Theme.Material3.* . Некоторые стили еще не имеют нового стиля в пространстве имен Material3, но большинство компонентов все равно унаследуют новый стиль после обновления родительской темы до Theme.Material3.* . Ниже мы видим, что кнопки теперь имеют новый закругленный дизайн.
В приведенном ниже файле тем изменена только родительская тема. Мы полностью заменим эту тему чуть позже. Некоторые атрибуты цвета устарели, а некоторые из созданных нами пользовательских стилей теперь являются стандартными в Material3, но мы хотели, чтобы вы сохранили их.
themes.xml
<style name="Theme.TipTime" parent="Theme.Material3.Light">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/green</item>
<item name="colorPrimaryVariant">@color/green_dark</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/blue</item>
<item name="colorSecondaryVariant">@color/blue_dark</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- For text input fields -->
<item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
<!-- For radio buttons -->
<item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
<!-- For switches -->
<item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>

4. Понимание цветовой тематики и роли цветов.
Цветовая система Material 3 использует организованный подход к применению цветов к пользовательскому интерфейсу. Ряд атрибутов из Theme.AppCompat по-прежнему используются. Однако в Theme.MaterialComponents.* было добавлено больше атрибутов, а в Theme.Material3.* ещё больше, поэтому важно проверить все экраны вашего приложения, чтобы убедиться, что никакие нереализованные свойства не передаются из базовой темы.
Понимание роли цвета
В теме Material 3 существует более двадцати атрибутов, связанных с цветом. На первый взгляд это может показаться сложным, но на самом деле есть несколько ключевых цветов, которые в сочетании с теми же 4-5 цветовыми ролями создают производные цвета.
К этим цветовым группам относятся:
- Основной цвет — основной цвет вашего приложения.
- Вторичный, дополнительный цвет вашего приложения
- Третичный цвет — это третий цвет, дополняющий основной и второстепенный.
- Error (используется для текста ошибок и диалоговых окон)
- Фон
- Поверхность, Вариант поверхности, Обратная поверхность
Роли для первичной, вторичной, третичной и ошибки распределяются следующим образом:
<базовый цвет> | базовый цвет |
на<базовый цвет> | цвет значков и текста, отображаемых на базовом цвете |
<базовый цвет>Контейнер | производный от базового цвета, используется для кнопок, диалоговых окон и т. д. |
на<базовый цвет>контейнере | цвет значков и текста в контейнере |
Например, плавающая кнопка действия со стандартным стилем в Material 3 использует Primary в качестве базового цвета, поэтому в качестве цвета фона кнопки используется primaryContainer , а в качестве цвета содержимого — onPrimaryContainer .
При ручной настройке темы следует как минимум убедиться, что атрибут on<base color> для каждого изменяемого базового цвета по-прежнему читаем.
Рекомендуется одновременно корректировать все роли в цветовой группе, чтобы избежать артефактов, возникающих на всем протяжении от базовой версии до вашего приложения.
Фоновые и базовые цвета поверхности, как правило, выполняют две функции: сам базовый цвет и on<base color> для значков или текста, отображаемых на нем.
5. Создание темы Material 3 с помощью Material Theme Builder
Material Theme Builder упрощает создание собственной цветовой схемы, позволяет использовать встроенный экспорт кода для перехода на цветовую систему M3 и воспользоваться преимуществами динамического изменения цвета. Подробнее на material.io/material-theme-builder
Тема оформления приложения Tip Time содержит несколько стилей для компонентов, однако большинство стилей являются стандартными для тем Material 3. Нам нужно обратить внимание только на два основных цвета: основной и дополнительный.
Они соответствуют основному зеленому цвету (#1B5E20) и дополнительному синему цвету (#0288D1).
Вы можете ввести эти цвета в конструктор тем Material и экспортировать готовую тему (при условии наличия ссылки на полный обзор в другом месте).
Обратите внимание, что введенные вами цвета могут изменять свой оттенок в соответствии с алгоритмом генерации цвета и обеспечивать комплементарные и читаемые цвета.
Ниже представлен набор значений, генерируемых при вводе пользовательских цветов.

6. Работа с файлами экспорта Material Theme Builder
В экспортированном архиве содержатся каталоги values и values-night/ с собственными файлами themes.xml, соответствующими светлой и темной темам. Все цвета определены в файле values/colors.xml.

Файлы можно скопировать как есть, но вам придётся изменить название темы в файле AndroidManifest.xml или в других файлах темы, чтобы они совпадали. Название по умолчанию, используемое в инструментах, — AppTheme.
Перезапустите приложение, и оно будет выглядеть практически так же. Одно заметное изменение касается переключателей и радиокнопок, выбранные состояния которых теперь оформлены в тонах основного цвета, а не второстепенных. В более крупных приложениях вам, возможно, придётся пересмотреть некоторые элементы дизайна.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tiptime">
<application ...>
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
7. Добавление динамического цвета
Используя подходящую тему Material 3, мы можем сделать пользовательский интерфейс динамичным, внеся в него несколько небольших изменений.
API динамических цветов позволяет применять динамический цвет ко всем Activity.
в приложении, для отдельных действий или для отдельных представлений или фрагментов.
В этом приложении мы будем применять динамический цвет глобально.
Создайте файл класса приложения.
class TipTimeApplication: Application() {
override fun onCreate() {
// Apply dynamic color
DynamicColors.applyToActivitiesIfAvailable(this)
}
}
Нам необходимо добавить ссылку на этот недавно созданный файл в манифест Android:
AndroidManifest.xml
< application android name=".TipTimeApplication
<!--- Other existing attributes –>
</application >
В системах Android 12 и выше анализируются обои пользователя (для схемы по умолчанию) для генерации нескольких тональных палитр. Значения из этих палитр используются для создания ThemeOverlay .
Класс DynamicColors регистрирует ActivityLifecycleCallbacks , который перехватывает вызов ActivityPreCreated для применения созданной системой динамической темы оформления или предоставленной вами.

8. Применение пользовательского наложения темы.
Наши инструменты позволяют экспортировать наложения тем оформления, но вы также можете создавать их вручную, если вам нужно переопределить небольшое количество атрибутов.
Наложение темы предназначено для использования совместно с другой темой и предоставляет только те значения, которые будут изменяться поверх базовой темы.
Предположим, что по какой-то причине, возможно, из-за особенностей брендинга, нам нужны основные цветовые тона в оттенках красного. Мы могли бы сделать это с помощью следующих файлов и атрибутов.
colors.xml
<resources>
<color name="overlay_light_primary">#9C4146</color>
<color name="overlay_light_onPrimary">#FFFFFF</color>
<color name= "overlay_light_primaryContainer">#FFDADB</color>
<color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >
themes_overlays.xml
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
<item name="colorPrimary">@color/overlay_light_primary</item>
<item name="colorOnPrimary">@color/overlay_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>
В приведенном выше коде Android 12 применит динамическую светлую тему и наложит ваши изменения поверх нее. В качестве альтернативы вы можете использовать любой допустимый ThemeOverlay в качестве родительского элемента, включая любой из следующих:
ThemeOverlay.Material3.Light
ThemeOverlay.Material3.Dark
ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark
ThemeOverlay.Material3.DynamicColors.DayNight
Чтобы использовать это наложение темы вместо стандартного Material, измените вызов метода DynamicColors.applyToActivitiesIfAvailable следующим образом:
DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

9. Добавление динамического цвета к пользовательским атрибутам
До сих пор мы переопределяли свойства, которые уже существуют в теме Material 3. Существует еще один возможный случай с динамическим цветом, когда нам может потребоваться присвоить один или несколько пользовательских атрибутов.
Когда приложение включает динамическую цветовую схему, оно получает доступ к 5 тональным палитрам — трем акцентным и двум нейтральным, с приблизительными ролями:
system_accent1 | Основные цветовые тона |
system_accent2 | Вторичные цветовые тона |
system_accent3 | Третичные цветовые тона |
system_neutral1 | Нейтральные фоны и поверхности |
system_neutral2 | Нейтральные поверхности и контуры |
Каждая палитра имеет несколько тональных ступеней, начиная с белого.
к черному: 0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000.
При разработке пользовательского интерфейса с динамической цветовой гаммой следует меньше думать о конкретном цвете и больше о соотношении тона и яркости этого компонента с другими элементами в дизайн-системе.
Допустим, вы хотите, чтобы значки были оформлены с использованием дополнительной палитры акцентов, и добавили атрибут для изменения цвета значков со следующей записью в файле attrs.xml.
attrs.xml
<resources>
<attr name="iconColor" format="color" />
</resources>
Ваша тема оформления может выглядеть примерно так:
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
<item name="iconColor">@android:color/system_accent2_600</item>
</style>
При переустановке приложения и смене обоев приложение автоматически подхватит эту дополнительную цветовую палитру.


Эти палитры предназначены для Android 12 (API 31), поэтому вам потребуется разместить соответствующие файлы в папках с суффиксом -v31 если только для вашего приложения не установлен минимальный SDK 31 или выше.
10. Резюме
В этом практическом занятии вы смогли:
- Добавьте зависимости, чтобы обновить вашу тему до Material 3.
- Разберитесь в новых цветовых группах и ролях.
- Разберитесь, как перейти от статической темы к динамической цветовой гамме.
- Разберитесь, как использовать наложения тем оформления и динамический цвет для пользовательских атрибутов темы.