Добавление динамического цвета в ваше приложение

1. Прежде чем начать

В этой лаборатории кода вы обновите стартовое приложение — приложение для расчета чаевых, чтобы использовать новые функции Material Design 3, позволяющие динамически оформлять пользовательский интерфейс приложения на основе обоев пользователя. Ниже приведены несколько скриншотов приложения с динамическим цветом. Вы также изучите некоторые дополнительные сценарии, позволяющие контролировать применение цветов.

Предварительные условия

Разработчики должны быть

  • Знание основных концепций тем в Android.
  • Удобно изменять тему приложения.

Что вы узнаете

  • Как отличить существующие темы Material Components от Material 3
  • Как обновить тему до Material 3
  • Как создавать темы с помощью наших инструментов и применять их
  • Как атрибуты темы связаны друг с другом

Что вам понадобится

2. Обзор стартового приложения

Приложение Tip Time — это приложение для расчета чаевых с возможностью настройки размера чаевых. Это один из примеров приложений из нашего учебного курса «Основы Android в Kotlin».

59906a9f19d6b804.png

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 или более раннюю версию, ознакомьтесь с инструкциями в документации по началу работы с компонентами Material Design для Android .

Где бы вы ни создавали свои темы, измените ссылки Theme.MaterialComponents.* на Theme.Material3.* . Некоторые стили еще не имеют нового стиля в пространстве имен Material3, но большинство компонентов все равно унаследуют новый стиль после обновления родительской темы до Theme.Material3.* . Ниже мы видим, что кнопки теперь имеют новую закругленную тему.

В файле тем ниже единственное, что было изменено, — это родительская тема. Мы полностью заменим эту тему через мгновение. Некоторые атрибуты цвета устарели, а некоторые из созданных нами пользовательских стилей теперь являются стандартными в Material3, но мы хотели, чтобы вы имели

темы.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>

f91e2acbac7cd469.png

4. Понимание цветовой тематики и цветовых ролей

Цветовая система Material 3 использует организованный подход к применению цветов в вашем пользовательском интерфейсе. Ряд атрибутов из Theme.AppCompat все еще используется. Однако в Theme.MaterialComponents.* было добавлено больше атрибутов и еще больше в Theme.Material3.* , поэтому важно проверить все экраны вашего приложения, чтобы убедиться, что из базовой темы не просачиваются никакие нереализованные свойства.

Понимание цветовых ролей

В теме Material 3 имеется более двадцати атрибутов, связанных с цветом. На первый взгляд это может показаться пугающим, но на самом деле существует несколько ключевых цветов, которые в сочетании с одними и теми же 4-5 цветовыми ролями создают производные цвета.

Эти цветовые группы:

  • Primary — основной цвет вашего приложения.
  • Вторичный, дополнительный цвет вашего приложения.
  • Третичный, либо третий цвет, дополняющий первичный и вторичный.
  • Ошибка, используется для текста ошибки и диалоговых окон.
  • Фон
  • Поверхность, SurfaceVariant, Обратная поверхность

Роли следующие: первичный, вторичный, третичный и ошибочный:

<базовый цвет>

Базовый цвет

на <базовом цвете>

цвет значков и текста, отображаемых на базовом цвете

<базовый цвет>Контейнер

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

on<базовый цвет>Контейнер

цвет значков и текста на контейнере

Например, кнопка плавающего действия со стилем по умолчанию в Материале 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 Theme Builder и экспортировать полную тему (при условии наличия ссылки на полный обзор в другом месте).

Имейте в виду, что вводимые вами цвета могут меняться по тону, чтобы соответствовать алгоритму генерации цвета и обеспечивать дополняющие и читаемые цвета.

Ниже приведено подмножество значений, генерируемых при вводе пользовательских цветов.

7f6c5a33f5233811.png

6. Работа с файлами экспорта Material Theme Builder

Архив экспорта содержит каталоги значений и Values-night/ с собственным файлом themes.xml, соответствующим светлой и темной темам. Все цвета определены в файлеvalues/colors.xml.

f66a64db2989a260.png

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

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

38a50ada47fd5ea4.png

<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 динамических цветов позволяет применять динамический цвет ко всем действиям.

в приложении, отдельных действиях или отдельных представлениях или фрагментах. Для

в этом приложении мы будем применять динамический цвет по всему миру.

Создайте файл класса приложения.

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 , чтобы применить созданное системой наложение динамической темы или предоставленное вами.

eba71f96f4ba9cdf.png

8. Применение пользовательского наложения темы

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

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

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

цвета.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

Чтобы использовать это наложение темы вместо материала по умолчанию, измените вызов DynamicColors.applyToActivitiesIfAvailable на:

DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

d87020776782036f.png

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>

Когда вы переустанавливаете приложение и меняете обои, приложение подберет эту дополнительную палитру.

11ef0035702640d9.png

264b2c2e74c5f574.png

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

10. Резюме

В этой лаборатории кода вы сможете:

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