Создайте полноценное приложение с помощью Relay и Jetpack Compose.

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

Relay — это набор инструментов, который позволяет командам разрабатывать компоненты пользовательского интерфейса в Figma и использовать их непосредственно в проектах Jetpack Compose. Это устраняет необходимость в утомительных спецификациях дизайна и циклах контроля качества, что помогает командам быстро создавать отличные пользовательские интерфейсы Android.

В этой лаборатории вы узнаете, как интегрировать пакеты Relay UI в процесс разработки Compose. Основное внимание уделяется методам интеграции, а не сквозному рабочему процессу. Чтобы узнать об общем рабочем процессе для Relay, см. базовое руководство по Relay .

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

  • Базовый опыт работы с Compose. Если вы еще этого не сделали, выполните лабораторную работу по основам Jetpack Compose .
  • Опыт работы с синтаксисом Kotlin.

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

  • Как импортировать пакеты пользовательского интерфейса.
  • Как интегрировать пакеты пользовательского интерфейса с архитектурой навигации и данных.
  • Как обернуть пакеты пользовательского интерфейса логикой контроллера.
  • Как сопоставить стили Figma с вашей темой Compose.
  • Как заменить пакеты пользовательского интерфейса существующими компонентами в сгенерированном коде.

Что ты построишь

  • Реалистичный дизайн приложения на основе пакетов Relay, предоставленных дизайнером. Приложение называется Reflect. Это приложение для ежедневного отслеживания, которое способствует развитию внимательности и хорошим привычкам. Он содержит коллекцию трекеров различных типов и пользовательский интерфейс для их добавления и управления. Приложение выглядит следующим образом:

Готовое приложение

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

2. Настройте

Получить код

Чтобы получить код для этой лаборатории кода, выполните одно из следующих действий:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • Перейдите в репозиторий relay-codelabs на GitHub, выберите нужную ветку, а затем нажмите «Код» > «Загрузить zip» и распакуйте загруженный zip-файл.

В любом случае main ветвь содержит стартовый код, а end ветвь — код решения.

Установите плагин Relay для Android Studio.

Если у вас еще нет плагина Relay for Android Studio, выполните следующие действия:

  1. В Android Studio нажмите «Настройки» > «Плагины» .
  2. В текстовом поле введите Relay for Android Studio .
  3. В расширении, которое появляется в результатах поиска, нажмите «Установить» .

Настройки плагина Android Studio

  1. Если вы увидите диалоговое окно примечания о конфиденциальности сторонних плагинов , нажмите «Принять» .
  2. Нажмите «ОК» > «Перезагрузить» .
  3. Если вы увидите диалоговое окно «Подтверждение выхода» , нажмите «Выход» .

Подключите Android Studio к Figma

Relay извлекает пакеты пользовательского интерфейса с помощью API Figma. Чтобы использовать его, вам понадобится бесплатная учетная запись Figma и токен личного доступа , поэтому они перечислены в разделе «Что вам понадобится» .

Если вы еще не подключили Android Studio к Figma, выполните следующие действия:

  1. В своей учетной записи Figma щелкните значок своего профиля вверху страницы и выберите «Настройки» .
  2. В разделе «Токены личного доступа» введите описание токена в текстовое поле, а затем нажмите Enter (или return в macOS). Токен генерируется.
  3. Нажмите «Копировать этот токен» .

Токен доступа, сгенерированный в Figma

  1. В Android Studio выберите «Инструменты» > «Настройки реле» . Появится диалоговое окно настроек реле .
  2. В текстовое поле Figma Access Token вставьте токен доступа и нажмите «ОК» . Ваша среда настроена.

3. Проверьте дизайн приложения.

Для приложения Reflect мы работали с дизайнером, который помог нам определить цвет, типографику, макет и поведение приложения. Мы создали эти проекты в соответствии с соглашениями Material Design 3 , чтобы приложение беспрепятственно работало с компонентами и темами Material.

Обзор главного экрана

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

Главный экран

В Figma наш дизайнер разделил этот экран на несколько компонентов, определил их API и упаковал их с помощью плагина Relay for Figma . После упаковки этих компонентов вы можете импортировать их в свой проект Android Studio.

Компонент главного экрана

Просмотрите экран добавления/редактирования

Экран добавления/редактирования позволяет пользователям добавлять или редактировать трекеры. Отображаемая форма немного отличается в зависимости от типа трекера.

Экран добавления/редактирования

Аналогично, этот экран разделен на несколько упакованных компонентов.

Добавлять/редактировать компоненты экрана

Обзор темы

Цвета и типографика для этого дизайна реализованы в виде стилей Figma на основе названий токенов Material Design 3. Это обеспечивает лучшую совместимость с темами Compose и компонентами Material.

Стили Фигмы

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

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

Чтобы получить ссылку на источник Figma, выполните следующие действия:

  1. В Figma нажмите «Импортировать файл» , а затем выберите файл ReflectDesign.fig , расположенный в папке проекта CompleteAppCodelab .
  2. Щелкните файл правой кнопкой мыши и выберите «Копировать ссылку» . Он понадобится вам в следующем разделе.

88afd168463bf7e5.png

Импортируйте пакеты пользовательского интерфейса в проект.

  1. В Android Studio откройте проект ./CompleteAppCodelab .
  2. Нажмите «Файл» > «Создать» > «Импортировать пакеты пользовательского интерфейса» . Появится диалоговое окно «Импорт пакетов пользовательского интерфейса» .
  3. В текстовое поле URL-адрес источника Figma вставьте URL-адрес, который вы скопировали в предыдущем разделе.

f75d0c3e17b6f75.png

  1. В текстовом поле Тема приложения введите com.google.relay.example.reflect.ui.theme.ReflectTheme . Это гарантирует, что созданные предварительные просмотры будут использовать пользовательскую тему.
  2. Нажмите "Далее . Вы увидите предварительный просмотр пакетов пользовательского интерфейса файла.
  3. Нажмите Создать . Пакеты импортируются в ваш проект.
  4. Перейдите на вкладку «Проект» и нажмите кнопку 2158ffa7379d2b2e.png стрелка расширителя рядом с папкой ui-packages .

Папка ui-packages

  1. Нажмите кнопку 2158ffa7379d2b2e.png стрелка расширителя рядом с одной из папок пакета, а затем обратите внимание, что она содержит исходный файл JSON и зависимости ресурсов.
  2. Откройте исходный файл JSON . Модуль Relay отображает предварительный просмотр пакета и его API.

a6105146c4cfb47.png

Сборка и генерация кода

  1. В верхней части Android Studio нажмите b3bc77f3c78cac1b.png Сделать проект . Сгенерированный код для каждого пакета добавляется в папку java/com.google.relay.example.reflect . Сгенерированные компоновочные элементы содержат всю информацию о макете и стиле из дизайна Figma.
  2. Откройте файл com/google/relay/example/reflect/range/Range.kt .
  3. Обратите внимание, что предварительные просмотры Compose создаются для каждого варианта компонента. При необходимости нажмите «Разделить» , чтобы панели кода и панели предварительного просмотра были расположены рядом друг с другом.

c0d21ab0622ad550.png

5. Интеграция компонентов

В этом разделе вы поближе познакомитесь с сгенерированным кодом трекера Switch.

Дизайн трекера Switch

  1. В Android Studio откройте файл com/google/relay/example/reflect/switch/Switch.kt .

Switch.kt (сгенерирован)

/**
 * This composable was generated from the UI Package 'switch'.
 * Generated code; don't edit directly.
 */
@Composable
fun Switch(
    modifier: Modifier = Modifier,
    isChecked: Boolean = false,
    emoji: String = "",
    title: String = ""
) {
    TopLevel(modifier = modifier) {
        if (isChecked) {
            ActiveOverlay(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f)) {}
        }
        TopLevelSynth(modifier = Modifier.rowWeight(1.0f)) {
            Label(modifier = Modifier.rowWeight(1.0f)) {
                Emoji(emoji = emoji)
                Title(
                    title = title,
                    modifier = Modifier.rowWeight(1.0f)
                )
            }
            Checkmark {
                if (isChecked) {
                    Icon()
                }
            }
        }
    }
}
  1. Обратите внимание на следующее:
  • Создается весь макет и стиль дизайна Figma.
  • Подэлементы делятся на отдельные составные элементы.
  • Составные превью создаются для всех вариантов дизайна.
  • Стили цвета и оформления жестко запрограммированы. Вы исправите это позже.

Вставьте трекер

  1. В Android Studio откройте файл java/com/google/relay/example/reflect/ui/components/TrackerControl.kt . Этот файл предоставляет данные и логику взаимодействия для систем отслеживания привычек.
  2. Создайте и запустите приложение в эмуляторе. В настоящее время этот компонент выводит необработанные данные из модели трекера.

5d56f8a7065066b7.png

  1. Импортируйте пакет com.google.relay.example.reflect.switch.Switch в файл.
  2. Замените Text(text = trackerData.tracker.toString()) блоком when , который вращается в поле trackerData.tracker.type .
  3. В теле when вызовите функцию Switch() Composable , если тип — TrackerType.BOOLEAN .

Ваш код должен выглядеть так:

TrackerControl.kt

// TODO: replace with Relay tracker components
when (trackerData.tracker.type) {
    TrackerType.BOOLEAN ->
        Switch(
          title = trackerData.tracker.name,
          emoji = trackerData.tracker.emoji
        )
    else ->
        Text(trackerData.tracker.toString())
}
  1. Восстановите проект. Теперь домашняя страница корректно отображает трекер Switch так, как было создано с использованием реальных данных.

4241e78b9f82075b.png

6. Добавьте состояние и взаимодействие

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

Оберните пакеты пользовательского интерфейса в Composable функцию контроллера

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

Чтобы создать контроллер для трекера Switch, выполните следующие действия:

  1. В Android Studio откройте файл java/com/google/relay/example/reflect/ui/components/SwitchControl.kt .
  2. В Composable функцию SwitchControl() передайте следующие параметры:
  • trackerData : объект TrackerData .
  • modifier : объект-декоратор
  • onLongClick : обратный вызов взаимодействия, позволяющий долго нажимать на трекеры для редактирования и удаления.
  1. Вставьте функцию Switch() и передайте combinedClickable модификатор Clickable для обработки щелчка и длительного нажатия.
  2. Передавайте значения из объекта TrackerData в функцию Switch() , включая метод isToggled() .

Завершенная функция SwitchControl() выглядит следующим образом:

SwitchControl.kt

package com.google.relay.example.reflect.ui.components

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.relay.example.reflect.model.Tracker
import com.google.relay.example.reflect.model.TrackerData
import com.google.relay.example.reflect.model.TrackerType
import com.google.relay.example.reflect.switch.Switch

/*
 * A component for controlling switch-type trackers.
 *
 * SwitchControl is responsible for providing interaction and state management to the stateless
 * composable [Switch] generated by Relay. [onLongClick] provides a way for callers to supplement
 * the control's intrinsic interactions with, for example, a context menu.
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SwitchControl(
    trackerData: TrackerData,
    modifier: Modifier = Modifier,
    onLongClick: (() -> Unit)? = null,
) {
    Switch(
        modifier
            .clip(shape = RoundedCornerShape(size = 32.dp))
            .combinedClickable(onLongClick = onLongClick) {
                trackerData.toggle()
            },
        emoji = trackerData.tracker.emoji,
        title = trackerData.tracker.name,
        isChecked = trackerData.isToggled(),
    )
}

@Preview
@Composable
fun SwitchControllerPreview() {
    val data = TrackerData(
        Tracker(
            emoji = "🍕",
            name = "Ate Pizza",
            type = TrackerType.BOOLEAN
        )
    )
    SwitchControl(data)
}
  1. В файле TrackerControl.kt удалите импорт Switch , а затем замените функцию Switch() вызовом функции SwitchControl() .
  2. Добавьте варианты для констант перечислителя TrackerType.RANGE и TrackerType.COUNT .

Завершенный блок when выглядит как этот фрагмент кода:

TrackerControl.kt

when (trackerData.tracker.type) {
    TrackerType.BOOLEAN ->
        SwitchControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
    TrackerType.RANGE ->
        RangeControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
    TrackerType.COUNT ->
        ValueControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
}
  1. Восстановите проект. Теперь вы можете отображать трекеры и взаимодействовать с ними. Главный экран готов.

b23b94f0034243d3.png

7. Сопоставьте существующие компоненты

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

Сопоставление текстового поля

На следующем изображении показан дизайн компонента Tracker Settings в диалоговом окне «Добавить/редактировать трекер» :

Дизайн компонента настроек коммутатора

Наш дизайнер использовал в дизайне ReflectTextField , для которого у нас уже есть реализация в коде, построенная поверх текстовых полей Material Design 3. Figma изначально не поддерживает текстовые поля, поэтому код по умолчанию, сгенерированный Relay, только выглядит как дизайн; это не функциональный контроль.

Чтобы протестировать текущую реализацию TrackerSettings :

  1. В Android Studio создайте и запустите приложение в эмуляторе.
  2. Нажмите и удерживайте строку трекера и выберите «Изменить» .
  3. Нажмите на текстовое поле Title и обратите внимание, что оно не реагирует на взаимодействие.

Чтобы заменить реальную реализацию этого элемента, вам нужны две вещи: пакет пользовательского интерфейса текстового поля и файл сопоставления . К счастью, наш дизайнер уже упаковал компоненты нашей системы дизайна в Figma и использовал в своем дизайне компонент текстового поля для Tracker Settings . По умолчанию этот вложенный пакет создается как зависимость, но для его замены вы используете сопоставление компонентов.

Компонент Figma для текстового поля с наложенным плагином Relay

Создайте файл сопоставления

Плагин Relay for Android Studio предоставляет ярлык для создания файлов сопоставления компонентов.

Чтобы создать файл сопоставления, выполните следующие действия:

  1. В Android Studio щелкните правой кнопкой мыши пакет пользовательского интерфейса text_field и выберите «Создать файл сопоставления» .

Создать пункт контекстного меню файла сопоставления

  1. Появится диалоговое окно файла сопоставления. Введите следующие параметры:
  • В разделе «Целевой составной объект» выберите « Использовать существующий составной объект» и введите com.google.relay.example.reflect.ui.components.ReflectTextField
  • В разделе «Сгенерированный файл» установите флажок «Создать реализацию» и снимите флажок «Создать предварительный просмотр компоновки».

e776585c3b838b10.png

  1. Нажмите Создать файл сопоставления. Это создаст следующий файл сопоставления:

text_field.json

{
  "target": "ReflectTextField",
  "package": "com.google.relay.example.reflect.ui.components",
  "generateImplementation": true,
  "generatePreviews": false,
}

Файлы сопоставления компонентов идентифицируют цель и пакет класса Compose, а также необязательную коллекцию объектов fieldMapping . Эти сопоставления полей позволяют преобразовывать параметры пакета в ожидаемые параметры Compose. В этом случае API идентичны, поэтому вам нужно указать только целевой класс.

  1. Восстановите проект.
  2. В файле trackersettings/ TrackerSettings.kt найдите сгенерированную составную функцию TitleFieldStyleFilledStateEnabledTextConfigurationsInputText() и обратите внимание, что она включает сгенерированный компонент ReflectTextField .

TrackerSettings.kt (сгенерирован)

@Composable
fun TitleFieldStyleFilledStateEnabledTextConfigurationsInputText(
    onTitleChanged: (String) -> Unit,
    title: String,
    modifier: Modifier = Modifier
) {
    ReflectTextField(
        onChange = onTitleChanged,
        labelText = "Title",
        leadingIcon = "search",
        trailingIcon = "cancel",
        supportingText = "Supporting text",
        inputText = title,
        state = State.Enabled,
        textConfigurations = TextConfigurations.InputText,
        modifier = modifier.fillMaxWidth(1.0f).requiredHeight(56.0.dp)
    )
}
  1. Восстановите проект. Теперь вы можете взаимодействовать с полями настроек трекера. Экран редактирования завершен.

8. Карта для создания тем

По умолчанию Relay генерирует буквальные значения для цветов и типографики. Это обеспечивает точность перевода, но не позволяет компонентам использовать систему тем Compose. Это очевидно, когда вы просматриваете свое приложение в темном режиме:

Предварительный просмотр главного экрана в темном режиме и отображении неправильных цветов

Компонент дневной навигации почти незаметен, а цвета неправильные. Чтобы исправить это, вы используете функцию сопоставления стилей в Relay, чтобы связать стили Figma с токенами темы Compose в сгенерированном коде. Это повышает визуальную согласованность между компонентами Relay и Material Design 3 и обеспечивает поддержку темного режима.

1fac916db14929bb.png

Создайте файл сопоставления стилей

  1. В Android Studio перейдите в каталог src/main/ui-package-resources и создайте новый каталог с именем style-mappings . В этом каталоге создайте файл figma_styles.json , содержащий следующий код:

Figma_styles.json

{
  "figma": {
    "colors": {
      "Reflect Light/background": "md.sys.color.background",
      "Reflect Dark/background": "md.sys.color.background",
      "Reflect Light/on-background": "md.sys.color.on-background",
      "Reflect Dark/on-background": "md.sys.color.on-background",
      "Reflect Light/surface": "md.sys.color.surface",
      "Reflect Dark/surface": "md.sys.color.surface",
      "Reflect Light/on-surface": "md.sys.color.on-surface",
      "Reflect Dark/on-surface": "md.sys.color.on-surface",
      "Reflect Light/surface-variant": "md.sys.color.surface-variant",
      "Reflect Dark/surface-variant": "md.sys.color.surface-variant",
      "Reflect Light/on-surface-variant": "md.sys.color.on-surface-variant",
      "Reflect Dark/on-surface-variant": "md.sys.color.on-surface-variant",
      "Reflect Light/primary": "md.sys.color.primary",
      "Reflect Dark/primary": "md.sys.color.primary",
      "Reflect Light/on-primary": "md.sys.color.on-primary",
      "Reflect Dark/on-primary": "md.sys.color.on-primary",
      "Reflect Light/primary-container": "md.sys.color.primary-container",
      "Reflect Dark/primary-container": "md.sys.color.primary-container",
      "Reflect Light/on-primary-container": "md.sys.color.on-primary-container",
      "Reflect Dark/on-primary-container": "md.sys.color.on-primary-container",
      "Reflect Light/secondary-container": "md.sys.color.secondary-container",
      "Reflect Dark/secondary-container": "md.sys.color.secondary-container",
      "Reflect Light/on-secondary-container": "md.sys.color.on-secondary-container",
      "Reflect Dark/on-secondary-container": "md.sys.color.on-secondary-container",
      "Reflect Light/outline": "md.sys.color.outline",
      "Reflect Dark/outline": "md.sys.color.outline",
      "Reflect Light/error": "md.sys.color.error",
      "Reflect Dark/error": "md.sys.color.error"
    },
    "typography": {
      "symbols": {
        "Reflect/headline/large": "md.sys.typescale.headline-large",
        "Reflect/headline/medium": "md.sys.typescale.headline-medium",
        "Reflect/headline/small": "md.sys.typescale.headline-small",
        "Reflect/title/large": "md.sys.typescale.title-large",
        "Reflect/title/medium": "md.sys.typescale.title-medium",
        "Reflect/title/small": "md.sys.typescale.title-small",
        "Reflect/body/large": "md.sys.typescale.body-large",
        "Reflect/body/medium": "md.sys.typescale.body-medium",
        "Reflect/body/small": "md.sys.typescale.body-small",
        "Reflect/label/large": "md.sys.typescale.label-large",
        "Reflect/label/medium": "md.sys.typescale.label-medium",
        "Reflect/label/small": "md.sys.typescale.label-small"
      },
      "subproperties": {
        "fontFamily": "font",
        "fontWeight": "weight",
        "fontSize": "size",
        "letterSpacing": "tracking",
        "lineHeightPx": "line-height"
      }
    }
  },
  "compose": {
    "colors": {
      "md.sys.color.background": "MaterialTheme.colorScheme.background",
      "md.sys.color.error": "MaterialTheme.colorScheme.error",
      "md.sys.color.error-container": "MaterialTheme.colorScheme.errorContainer",
      "md.sys.color.inverse-on-surface": "MaterialTheme.colorScheme.inverseOnSurface",
      "md.sys.color.inverse-surface": "MaterialTheme.colorScheme.inverseSurface",
      "md.sys.color.on-background": "MaterialTheme.colorScheme.onBackground",
      "md.sys.color.on-error": "MaterialTheme.colorScheme.onError",
      "md.sys.color.on-error-container": "MaterialTheme.colorScheme.onErrorContainer",
      "md.sys.color.on-primary": "MaterialTheme.colorScheme.onPrimary",
      "md.sys.color.on-primary-container": "MaterialTheme.colorScheme.onPrimaryContainer",
      "md.sys.color.on-secondary": "MaterialTheme.colorScheme.onSecondary",
      "md.sys.color.on-secondary-container": "MaterialTheme.colorScheme.onSecondaryContainer",
      "md.sys.color.on-surface": "MaterialTheme.colorScheme.onSurface",
      "md.sys.color.on-surface-variant": "MaterialTheme.colorScheme.onSurfaceVariant",
      "md.sys.color.on-tertiary": "MaterialTheme.colorScheme.onTertiary",
      "md.sys.color.on-tertiary-container": "MaterialTheme.colorScheme.onTertiaryContainer",
      "md.sys.color.outline": "MaterialTheme.colorScheme.outline",
      "md.sys.color.primary": "MaterialTheme.colorScheme.primary",
      "md.sys.color.primary-container": "MaterialTheme.colorScheme.primaryContainer",
      "md.sys.color.secondary": "MaterialTheme.colorScheme.secondary",
      "md.sys.color.secondary-container": "MaterialTheme.colorScheme.secondaryContainer",
      "md.sys.color.surface": "MaterialTheme.colorScheme.surface",
      "md.sys.color.surface-variant": "MaterialTheme.colorScheme.surfaceVariant",
      "md.sys.color.tertiary": "MaterialTheme.colorScheme.tertiary",
      "md.sys.color.tertiary-container": "MaterialTheme.colorScheme.tertiaryContainer"
    },
    "typography": {
      "symbols": {
        "md.sys.typescale.display-large": "MaterialTheme.typography.displayLarge",
        "md.sys.typescale.display-medium": "MaterialTheme.typography.displayMedium",
        "md.sys.typescale.display-small": "MaterialTheme.typography.displaySmall",
        "md.sys.typescale.headline-large": "MaterialTheme.typography.headlineLarge",
        "md.sys.typescale.headline-medium": "MaterialTheme.typography.headlineMedium",
        "md.sys.typescale.headline-small": "MaterialTheme.typography.headlineSmall",
        "md.sys.typescale.title-large": "MaterialTheme.typography.titleLarge",
        "md.sys.typescale.title-medium": "MaterialTheme.typography.titleMedium",
        "md.sys.typescale.title-small": "MaterialTheme.typography.titleSmall",
        "md.sys.typescale.body-large": "MaterialTheme.typography.bodyLarge",
        "md.sys.typescale.body-medium": "MaterialTheme.typography.bodyMedium",
        "md.sys.typescale.body-small": "MaterialTheme.typography.bodySmall",
        "md.sys.typescale.label-large": "MaterialTheme.typography.labelLarge",
        "md.sys.typescale.label-medium": "MaterialTheme.typography.labelMedium",
        "md.sys.typescale.label-small": "MaterialTheme.typography.labelSmall"
      },
      "subproperties": {
        "font": "fontFamily",
        "weight": "fontWeight",
        "size": "fontSize",
        "tracking": "letterSpacing",
        "line-height": "lineHeight"
      }
    },
    "options": {
      "packages": {
        "MaterialTheme": "androidx.compose.material3"
      }
    }
  }
}

Файлы сопоставления тем структурированы двумя объектами верхнего уровня: figma и compose . Внутри этих объектов определения цвета и типа связаны между обеими средами через промежуточные токены. Это позволяет нескольким стилям Figma сопоставляться с одной записью темы Compose, что полезно, когда вы поддерживаете светлые и темные темы.

  1. Просмотрите файл сопоставления, особенно то, как он переназначает свойства типографики из Figma на то, что ожидает Compose.

Повторный импорт пакетов пользовательского интерфейса

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

Чтобы повторно импортировать пакеты пользовательского интерфейса, выполните следующие действия:

  1. В Android Studio нажмите «Файл» > «Создать» > «Импортировать пакеты пользовательского интерфейса» . Появится диалоговое окно «Импорт пакетов пользовательского интерфейса» .
  2. В текстовом поле URL-адрес источника Figma введите URL-адрес исходного файла Figma.
  3. Установите флажок «Перевести стили Figma в композицию темы» .
  4. Выберите Импортировать пользовательскую конфигурацию . Щелкните значок папки, затем выберите только что созданный файл: src/main/ui-package-resources/style-mappings/figma_styles.json .
  5. Нажмите "Далее . Вы увидите предварительный просмотр пакетов пользовательского интерфейса файла.
  6. Нажмите Создать . Пакеты импортируются в ваш проект.

Диалоговое окно «Импорт пакетов пользовательского интерфейса»

  1. Перестройте проект, а затем откройте файл switch/Switch.kt чтобы просмотреть сгенерированный код.

Switch.kt (сгенерирован)

@Composable
fun ActiveOverlay(
    modifier: Modifier = Modifier,
    content: @Composable RelayContainerScope.() -> Unit
) {
    RelayContainer(
        backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
        isStructured = false,
        radius = 32.0,
        content = content,
        modifier = modifier.fillMaxWidth(1.0f).fillMaxHeight(1.0f)
    )
}
  1. Обратите внимание, что для параметра backgroundColor установлено значение поля MaterialTheme.colorScheme.surfaceVariant в объекте темы Compose.
  2. Запустите проект и включите темный режим в эмуляторе. Тема применена правильно, визуальные ошибки исправлены.

6cf2aa19fabee292.png

9. Поздравления

Поздравляем! Вы узнали, как интегрировать Relay в свои приложения Compose!

Узнать больше