Перенос XML-тем в Material 3 в Compose

Когда вы внедряете Compose в существующее приложение, вам необходимо перенести темы Material XML, чтобы использовать MaterialTheme для компонентов Compose. Это означает, что у темы вашего приложения будет два источника истины: тема на основе View и тема Compose. Если вы захотите изменить стиль, вам придется сделать это в нескольких местах. После полного перехода на Compose удалите темы XML.

Для переноса цветов можно использовать инструмент Material Theme Builder.

При переходе с XML на Compose перенесите темы в Material 3 Compose.

Глоссарий

Термин Определение
MaterialTheme Компонуемая функция, которая предоставляет темы (цвета, типографику, формы) для компонентов Compose UI.
Shapes Объект Compose, используемый для определения пользовательских форм компонентов для MaterialTheme.
Typography Объект Compose, используемый для определения пользовательских стилей текста (семейств шрифтов, размеров, насыщенности) для MaterialTheme.
ColorScheme Объект Compose, используемый для определения пользовательских цветовых схем для MaterialTheme.
XML-тема Система тем Android, определенная в XML-файлах и используемая системой View.

Ограничения

Перед переносом ознакомьтесь со следующими ограничениями:

  • В этом руководстве рассматривается только переход на Material 3. Если вы хотите перейти с альтернативных систем проектирования, ознакомьтесь с информацией о Material 2 или специальных системах проектирования в Compose.
  • Конечная цель — полный переход на Compose, что позволит удалить темы XML. В этом руководстве объясняется, как выполнить перенос, но не рассказывается, как окончательно удалить темы XML.

Шаг 1. Оцените систему проектирования

Определите, какая система проектирования используется в проекте XML View. Проанализируйте путь миграции и необходимые шаги для переноса существующей системы проектирования в Material 3 в Compose.

Шаг 2. Найдите исходные файлы темы

В XML-файле вы пишете ?attr/colorPrimary. В Compose вы получаете доступ к значениям темы с помощью MaterialTheme.*:

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

Ресурсы, такие как строки, можно использовать повторно, и их не нужно переносить.

Шаг 3. Перенесите цвета

Основной принцип. В XML используются именованные шестнадцатеричные коды цветов. В Material 3 используются семантические роли (например, primary, onPrimary, surface). Перестаньте называть цвета по их шестнадцатеричному коду, называйте их по их роли.

Примеры:

Название цвета в XML Роль Material 3
colorPrimary primary
colorPrimaryDark/colorPrimaryVariant primaryContainer или secondary
colorAccent secondary или tertiary
colorOnPrimary onPrimary
android:colorBackground background
colorSurface surface
colorOnSurface onSurface
colorError error
colorOnError onError
colorOutline outline
colorSurfaceVariant surfaceVariant
colorOnSurfaceVariant onSurfaceVariant

Перенесите тёмную и светлую цветовые схемы из XML в их эквиваленты в Material 3 Compose.

Шаг 4. Перенесите пользовательские фигуры и типографику

  • Если в вашем приложении используются пользовательские фигуры:

    1. В коде Compose определите объект Shapes, чтобы воспроизвести определения фигур XML.
    2. Передайте этот объект Shapes в MaterialTheme.

      Подробнее о фигурах…

  • Если в вашем приложении используется собственная типографика:

    1. В коде Compose определите объект Typography, чтобы воспроизвести стили текста и определения шрифтов XML.
    2. Передайте объект Typography в MaterialTheme.

      Подробнее о типографике…

Роль Compose Название XML
displayLarge TextAppearance.Material3.DisplayLarge
displayMedium TextAppearance.Material3.DisplayMedium
displaySmall TextAppearance.Material3.DisplaySmall
headlineLarge TextAppearance.Material3.HeadlineLarge
headlineMedium TextAppearance.Material3.HeadlineMedium
headlineSmall TextAppearance.Material3.HeadlineSmall
titleLarge TextAppearance.Material3.TitleLarge
titleMedium TextAppearance.Material3.TitleMedium
titleSmall TextAppearance.Material3.TitleSmall
bodyLarge TextAppearance.Material3.BodyLarge
bodyMedium TextAppearance.Material3.BodyMedium
bodySmall TextAppearance.Material3.BodySmall
labelLarge TextAppearance.Material3.LabelLarge
labelMedium TextAppearance.Material3.LabelMedium
labelSmall TextAppearance.Material3.LabelSmall

Шаг 5. Перенесите стили (styles.xml)

XML-стили (styles.xml) определяют внешний вид следующих элементов:

  1. Виджеты, компоненты, темы для окон и диалоговых окон
  2. Параметры текста
  3. Темы и наложения
  4. Фигуры

Представления и компоненты XML объединяют несколько атрибутов для создания стиля. Они задают стили из styles.xml двумя разными способами:

  1. Задайте "style="@style/..." непосредственно в XML View.
  2. Косвенное и неявное задание стиля для компонента в рамках более крупной темы (theme.xml).

В Compose нет прямого эквивалента стилей. Вместо этого они передаются как параметры или модификаторы в composable-функции с помощью нового экспериментального Styles API, определенного в AppTheme, или путем создания многоуровневых многократно используемых вариантов composable-функций с заданным стилем.

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

  • Шаблон. Если в элементе XML используется собственный стиль (например, style="@style/MyPrimaryButton"), не пытайтесь воспроизвести его в строке. Вместо этого предложите создать конкретную composable-функцию.
  • Пример:
    • XML: <Button style="@style/MyPrimaryButton" ... />
    • Написать: MyPrimaryButton(onClick = { ... })
  • Общие группы атрибутов. Если стиль задает общие модификаторы (например, отступы и высоту), извлеките их в читаемое свойство расширения или общую переменную Modifier.

Типичные примеры

XML Написать
Theme.Material3.* MaterialTheme(colorScheme, typography, shapes) { }
TextAppearance.Material3.BodyMedium TextStyle(...), определенный в Typography(bodyMedium = ...)
ShapeAppearance.*.SmallComponent Shapes(small = RoundedCornerShape(X.dp))
Widget.Material3.Button Button(colors = ButtonDefaults.buttonColors(...))
Widget.Material3.CardView Card(shape=..., elevation=..., colors=...)
Widget.*.TextInputLayout.OutlinedBox OutlinedTextField(colors = OutlinedTextFieldDefaults.colors(...))
Widget.*.Chip.Filter FilterChip(colors = FilterChipDefaults.filterChipColors(...))
Widget.*.Toolbar.Primary TopAppBar(colors = TopAppBarDefaults.topAppBarColors(...))
Widget.*.FloatingActionButton FloatingActionButton(containerColor = ...)
backgroundTint containerColor (ComponentDefaults.ComponentColors())
android:textColor contentColor (ComponentDefaults.ComponentColors())
cornerRadius shape = RoundedCornerShape(X.dp)
android:elevation elevation = ComponentDefaults.elevation(defaultElevation = X.dp)
android:padding contentPadding = PaddingValues(...) или Modifier.padding()
android:minHeight Modifier.heightIn(min = X.dp)
strokeColor + strokeWidth border = BorderStroke(width, color)
android:textSize fontSize = X.sp (TextStyle)

Шаг 6. Проверьте перенос темы

Всегда используйте существующие значения темы из исходной XML-темы в качестве источника истины для нового тематического оформления Material Design в Compose. Чтобы сохранить единообразие бренда и избежать визуальных регрессий, не создавайте новые значения тем во время переноса.

Убедитесь, что все новые значения темы Compose соответствуют существующим значениям XML. Не задавайте в коде перенесенные значения.