Utwórz kompletną aplikację, korzystając z usług Relay i Jetpack Compose

1. Zanim zaczniesz

Relay to zestaw narzędzi, które pozwalają zespołom projektować komponenty interfejsu w aplikacji Figma i używać ich bezpośrednio w projektach Jetpack Compose. Eliminuje konieczność żmudnego definiowania projektu i cykli kontroli jakości, dzięki czemu zespoły mogą szybko tworzyć świetne interfejsy Androida.

Z tego ćwiczenia w Codelabs dowiesz się, jak zintegrować pakiety interfejsu usługi Relay z procesem programistycznym usługi Compose. Skupia się na technikach integracji, a nie na całym przepływie pracy. Aby poznać ogólny przepływ pracy z usługą Relay, zobacz podstawowy samouczek dotyczący usługi Relay.

Wymagania wstępne

  • Podstawowa obsługa funkcji tworzenia wiadomości. Jeśli nie masz jeszcze za sobą ćwiczenia z programowania, wykonaj podstawowe informacje o Jetpack Compose.
  • Doświadczenie w korzystaniu ze składni Kotlin.

Czego się nauczysz

  • Jak importować pakiety interfejsu.
  • Jak zintegrować pakiety UI z nawigacją i architekturą danych.
  • Jak opakowywać pakiety UI za pomocą logiki kontrolera.
  • Jak zmapować style Figma do motywu tworzenia wiadomości.
  • Jak zastąpić pakiety interfejsu istniejącymi elementami kompozycyjnymi w wygenerowanym kodzie.

Co utworzysz

  • Realistyczny projekt aplikacji oparty na pakietach usługi przekaźnika dostarczonych przez projektanta. Reflect to aplikacja do codziennego monitorowania, która promuje uważność i dobre nawyki. Zawiera on kolekcję trackerów różnego typu oraz interfejs, za pomocą którego można je dodawać i nimi zarządzać. Aplikacja wygląda jak na tym obrazie:

Końcowa aplikacja

Czego potrzebujesz

2. Konfiguracja

Pobierz kod

Aby pobrać kod do tego ćwiczenia z programowania, wykonaj jedną z tych czynności:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • Przejdź do repozytorium relay-codelabs na GitHubie, wybierz odpowiednią gałąź i kliknij Kod > Pobierz plik ZIP i rozpakuj pobrany plik.

W obu przypadkach gałąź main zawiera kod startowy, a gałąź end – kod rozwiązania.

Instalowanie wtyczki Relay for Android Studio

Jeśli nie masz jeszcze wtyczki Relay for Android Studio, wykonaj te czynności:

  1. W Android Studio kliknij Ustawienia > Wtyczki.
  2. W polu tekstowym wpisz Relay for Android Studio.
  3. Obok rozszerzenia, które pojawi się w wynikach wyszukiwania, kliknij Zainstaluj.

Ustawienia wtyczki Android Studio

  1. Jeśli pojawi się okno Uwagi na temat ochrony prywatności dotyczące wtyczek innych firm, kliknij Akceptuj.
  2. Kliknij przycisk OK > Uruchom ponownie.
  3. Jeśli pojawi się okno Potwierdź wyjście, kliknij Zakończ.

Łączenie Android Studio z kontem Figma

Relay pobiera pakiety UI za pomocą interfejsu Figma API. Aby z niego korzystać, potrzebujesz bezpłatnego konta Figma i osobistego tokena dostępu, dlatego są one wymienione w sekcji Co będzie Ci potrzebne.

Jeśli Android Studio nie jest jeszcze połączony z aplikacją Figma, wykonaj te czynności:

  1. Na koncie Figma kliknij ikonę profilu na górze strony i wybierz Ustawienia.
  2. W sekcji Osobiste tokeny dostępu wpisz opis tokena w polu tekstowym, a następnie naciśnij Enter (lub return w systemie macOS). Zostanie wygenerowany token.
  3. Kliknij Kopiuj ten token.

Token dostępu wygenerowany w aplikacji Figma

  1. W Android Studio wybierz kolejno Narzędzia > Relay Settings (Ustawienia przekaźnika). Pojawi się okno Relay settings (Ustawienia przekaźnika).
  2. W polu tekstowym Token dostępu Figma wklej token dostępu i kliknij OK. Środowisko jest skonfigurowane.

3. Sprawdzanie projektu aplikacji

We współpracy z projektantem aplikacji Reflect mogliśmy określić kolor, typografię, układ i działanie aplikacji. Stworzyliśmy te projekty zgodnie z konwencjami Material Design 3, aby aplikacja bezproblemowo współpracowała z komponentami i motywami Material Design.

Przeglądanie ekranu głównego

Ekran główny zawiera listę zdefiniowanych przez użytkownika trackerów. Oferuje również możliwości zmiany dnia aktywności i tworzenia innych trackerów.

Ekran główny

W aplikacji Figma nasz projektant podzielił ten ekran na wiele komponentów, określił ich interfejsy API i spakował je z wtyczką Relay for Figma. Po spakowaniu komponentów możesz je zaimportować do projektu w Android Studio.

Komponent ekranu głównego

Przejrzyj ekran dodawania/edytowania.

Ekran dodawania/edycji umożliwia użytkownikom dodawanie i edytowanie trackerów. Wyświetlony formularz różni się nieco w zależności od typu trackera.

Ekran dodawania/edytowania

Ten ekran jest podzielony na kilka części.

Dodawanie/edytowanie komponentów ekranu

Sprawdź motyw

Kolory i typografia tego projektu są zaimplementowane jako style Figma na podstawie nazw tokenów interfejsu Material Design 3. Zapewnia to lepszą współpracę z motywami Compose i komponentami Material.

Style Figmy

4. Importuj pakiety interfejsu

Zanim zaimportujesz pakiety interfejsu do projektu, musisz przesłać źródło projektu do Figmy.

Aby uzyskać link do źródła aplikacji Figma, wykonaj te czynności:

  1. W aplikacji Figma kliknij Import file (Importuj plik), a następnie wybierz plik ReflectDesign.fig znajdujący się w folderze projektu CompleteAppCodelab.
  2. Kliknij plik prawym przyciskiem myszy i wybierz Kopiuj link. Będzie on potrzebny w następnej sekcji.

88afd168463bf7e5.png

Importowanie pakietów UI do projektu

  1. W Android Studio otwórz projekt ./CompleteAppCodelab.
  2. Kliknij Plik > Nowe > Importuj pakiety interfejsu. Pojawi się okno Importuj pakiety interfejsu.
  3. W polu tekstowym Źródłowy adres URL aplikacji Figma wklej adres URL skopiowany w poprzedniej sekcji.

f75d0c3e17b6f75.png

  1. W polu tekstowym Motyw aplikacji wpisz com.google.relay.example.reflect.ui.theme.ReflectTheme. Dzięki temu wygenerowane podglądy będą korzystać z motywu niestandardowego.
  2. Kliknij Dalej. Zobaczysz podgląd pakietów UI pliku.
  3. Kliknij Utwórz. Pakiety zostaną zaimportowane do projektu.
  4. Otwórz kartę Projekt, a potem kliknij 2158ffa7379d2b2e.pngstrzałkę rozwijania obok folderu ui-packages.

Folder ui-packages

  1. Kliknij 2158ffa7379d2b2e.pngstrzałkę rozwijania obok jednego z folderów pakietów i zauważ, że zawiera on plik źródłowy JSON i zależności zasobów.
  2. Otwórz plik źródłowy JSON. Moduł Relay wyświetla podgląd pakietu i jego interfejsu API.

a6105146c4cfb47.png

Kompilowanie i generowanie kodu

  1. U góry Android Studio kliknij b3bc77f3c78cac1b.png Utwórz projekt. Wygenerowany kod dla każdego pakietu jest dodawany do folderu java/com.google.relay.example.reflect. Wygenerowane elementy kompozycyjne zawierają wszystkie informacje o układzie i stylu z projektu Figma.
  2. Otwórz plik com/google/relay/example/reflect/range/Range.kt.
  3. Zwróć uwagę, że podgląd tworzenia wiadomości jest generowany dla każdej odmiany komponentu. W razie potrzeby kliknij Podziel, aby kody i okienki podglądu były widoczne obok siebie.

c0d21ab0622ad550.png

5. Integrowanie komponentów

W tej sekcji przyjrzeć się bliżej wygenerowanemu kodowi trackera Switch.

Konstrukcja trackera Switch

  1. Otwórz plik com/google/relay/example/reflect/switch/Switch.kt w Android Studio.

Switch.kt (wygenerowano)

/**
 * 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. Uwaga:
  • Wygenerowany zostanie cały układ i styl z projektu Figma.
  • Elementy podrzędne są podzielone na osobne elementy kompozycyjne.
  • Kompozycyjne wersje przedpremierowe są generowane dla wszystkich wersji projektu.
  • Style kolorów i typografii są zapisywane na stałe. Popraw to później.

Włóż tracker

  1. Otwórz plik java/com/google/relay/example/reflect/ui/components/TrackerControl.kt w Android Studio. Ten plik dostarcza danych i interakcji z narzędziami do śledzenia nawyków.
  2. Utwórz i uruchom aplikację w emulatorze. Obecnie ten komponent generuje nieprzetworzone dane z modelu śledzenia.

5d56f8a7065066b7.png

  1. Zaimportuj do pliku pakiet com.google.relay.example.reflect.switch.Switch.
  2. Zastąp Text(text = trackerData.tracker.toString()) blokiem when przestawnym w polu trackerData.tracker.type.
  3. Gdy typ to TrackerType.BOOLEAN, w treści bloku when wywołaj funkcję Composable Switch().

Twój kod powinien wyglądać następująco:

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. Utwórz projekt od nowa. Teraz strona główna poprawnie renderuje tracker Switch zgodnie z projektem opartym na danych bieżących.

4241e78b9f82075b.png

6. Dodaj stan i interakcję

Pakiety UI są bezstanowe. Wynik renderowania jest prostym wynikiem przekazanych parametrów. Prawdziwe aplikacje wymagają jednak interakcji i stanu. Moduły obsługi interakcji mogą być przekazywane do wygenerowanych elementów kompozycyjnych tak samo jak inne parametry, ale gdzie zachowywany jest stan edytowany przez te moduły? Jak uniknąć przekazywania tego samego modułu obsługi do każdej instancji? Jak można wyodrębnić kompozycje opakowań w elementy kompozycyjne wielokrotnego użytku? W takich przypadkach zalecamy pakowanie wygenerowanych pakietów w niestandardową funkcję Composable.

Opakowywanie pakietów UI w funkcji Composable kontrolera

Pakowanie pakietów interfejsu w funkcji Composable kontrolera pozwala dostosować prezentację lub logikę biznesową oraz, w razie potrzeby, zarządzać stanem lokalnym. Projektanci nadal mogą aktualizować pierwotny pakiet UI w Figmie bez konieczności aktualizowania kodu opakowań.

Aby utworzyć kontroler dla Switch trackera, wykonaj te czynności:

  1. Otwórz plik java/com/google/relay/example/reflect/ui/components/SwitchControl.kt w Android Studio.
  2. W funkcji Composable SwitchControl() przekazuj te parametry:
  • trackerData: obiekt TrackerData
  • modifier: obiekt dekoratora
  • onLongClick: wywołanie zwrotne interakcji, które umożliwia edytowanie i usuwanie elementów śledzących.
  1. Wstaw funkcję Switch() i przekaż modyfikator combinedClickable, aby obsłużyć kliknięcie i przytrzymanie.
  2. Przekazuj wartości z obiektu TrackerData do funkcji Switch(), w tym do metody isToggled().

Ukończona funkcja SwitchControl() wygląda podobnie do tego fragmentu kodu:

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. W pliku TrackerControl.kt usuń import Switch, a następnie zastąp funkcję Switch() wywołaniem funkcji SwitchControl().
  2. Dodaj przypadki dla stałych wyliczających TrackerType.RANGE i TrackerType.COUNT.

Ukończony blok when wygląda tak:

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. Utwórz projekt od nowa. Teraz możesz wyświetlać lokalizatory i wchodzić z nimi w interakcję. Ekran główny jest gotowy.

b23b94f0034243d3.png

7. Zmapuj istniejące komponenty

Relay pozwala programistom dostosować wygenerowany kod przez zastąpienie pakietów UI istniejącymi elementami kompozycyjnymi. To świetny sposób na umieszczenie w kodzie gotowych komponentów lub nawet niestandardowych systemów projektowania.

Zmapuj pole tekstowe

Poniższy obraz przedstawia wygląd komponentu Tracker Settings w oknie Dodaj/edytuj tag śledzenia:

Konstrukcja komponentu Przełącz ustawienia

Nasz projektant użył do swojego projektu ReflectTextField. Mamy już implementację w kodzie opartym na polach tekstowych Material Design 3. Aplikacja Figma nie obsługuje natywnie pól tekstowych, więc domyślny kod generowany przez usługę Relay wygląda tylko tak, jak w projekcie. nie jest to element funkcjonalny.

Aby przetestować bieżącą implementację w usłudze TrackerSettings:

  1. W Android Studio skompiluj i uruchom aplikację w emulatorze.
  2. Przytrzymaj w wierszu trackera i wybierz Edytuj.
  3. Kliknij pole tekstowe Title. Pamiętaj, że nie odpowiada ono na interakcję.

Aby zastąpić rzeczywistą implementację tego elementu, potrzebujesz 2 elementów: pakietu interfejsu pola tekstowego i pliku mapowania. Na szczęście nasz projektant spakował już komponenty naszego systemu projektowania w Figmie i użył komponentu pola tekstowego w projekcie Tracker Settings. Domyślnie ten zagnieżdżony pakiet jest generowany jako zależność, ale do ich zamiany używasz mapowania komponentów.

Komponent Figma dla pola tekstowego z nałożonym wtyczką Relay

Tworzenie pliku mapowania

Wtyczka Relay for Android Studio zapewnia skrót do tworzenia plików mapowania komponentów.

Aby utworzyć plik mapowania, wykonaj te czynności:

  1. W Android Studio kliknij prawym przyciskiem myszy pakiet interfejsu text_field, a następnie wybierz Wygeneruj plik mapowania.

Generuj pozycję menu kontekstowego pliku mapowania

  1. Pojawi się okno pliku mapowania. Wpisz te opcje:
  • W sekcji Element docelowy kompozycyjny wybierz Użyj istniejącego elementu kompozycyjnego i wpisz com.google.relay.example.reflect.ui.components.ReflectTextField
  • W sekcji Wygenerowany plik zaznacz Wygeneruj implementację i odznacz Wygeneruj podgląd tworzenia wiadomości

e776585c3b838b10.png

  1. Kliknij Wygeneruj plik mapowania. Spowoduje to wygenerowanie tego pliku mapowania:

text_field.json

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

Pliki mapowania komponentów określają cel i pakiet klasy Compose oraz opcjonalny zbiór obiektów fieldMapping. Te mapowania pól umożliwiają przekształcenie parametrów pakietu w oczekiwanych parametrów tworzenia wiadomości. W tym przypadku interfejsy API są identyczne, wystarczy więc określić tylko klasę docelową.

  1. Utwórz projekt od nowa.
  2. W pliku TrackerSettings.kt pliku trackersettings/ znajdź wygenerowaną funkcję kompozycyjną TitleFieldStyleFilledStateEnabledTextConfigurationsInputText(). Pamiętaj, że zawiera ona wygenerowany komponent ReflectTextField.

TrackerSettings.kt (wygenerowany)

@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. Utwórz projekt od nowa. Teraz możesz korzystać z pól ustawień trackera. Ekran edycji jest gotowy.

8. Motywy map do tworzenia wiadomości

Domyślnie Relay generuje literałowe wartości kolorów i typografii. Zapewnia to dokładność translacji, ale uniemożliwia komponentom korzystanie z systemu motywów tworzenia wiadomości. Jest to oczywiste w przypadku korzystania z aplikacji w trybie ciemnym:

Podgląd ekranu głównego w trybie ciemnym, który wyświetla nieprawidłowe kolory

Komponent nawigacji według dnia jest prawie niewidoczny, a kolory są błędne. Aby rozwiązać ten problem, użyj funkcji mapowania stylów w usłudze Relay, aby połączyć style Figma z tokenami tworzenia motywu w wygenerowanym kodzie. Zwiększa to wizualną spójność między komponentami Relay i Material Design 3 oraz włącza obsługę trybu ciemnego.

1fac916db14929bb.png

Tworzenie pliku mapowania stylów

  1. W Android Studio przejdź do katalogu src/main/ui-package-resources i utwórz nowy katalog o nazwie style-mappings. W tym katalogu utwórz plik figma_styles.json zawierający ten kod:

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"
      }
    }
  }
}

Pliki mapowania motywów zawierają 2 obiekty najwyższego poziomu: figma i compose. Wewnątrz tych obiektów definicje koloru i typu są połączone między oboma środowiskami za pomocą tokenów pośrednich. Umożliwia to zmapowanie wielu stylów Figmy na jedną pozycję motywu tworzenia wiadomości, co jest przydatne, gdy obsługujesz jasne i ciemne motywy.

  1. Przejrzyj plik mapowania, zwłaszcza sposób mapowania właściwości typograficznych z Figmy na właściwości Compose.

Ponownie zaimportuj pakiety interfejsu

Po utworzeniu pliku mapowania musisz ponownie zaimportować wszystkie pakiety UI do projektu, ponieważ podczas początkowego importowania wszystkie wartości stylu Figma zostały odrzucone, ponieważ nie przesłano pliku mapowania.

Aby ponownie zaimportować pakiety interfejsu, wykonaj te czynności:

  1. W Android Studio kliknij Plik > Nowe > Importuj pakiety interfejsu. Pojawi się okno Importuj pakiety interfejsu.
  2. W polu tekstowym „Źródłowy adres URL aplikacji Figma” wpisz adres URL pliku źródłowego aplikacji Figma.
  3. Zaznacz pole wyboru Przetłumacz style Figma na motyw Utwórz.
  4. Kliknij Importuj konfigurację niestandardową. Kliknij ikonę folderu i wybierz nowo utworzony plik: src/main/ui-package-resources/style-mappings/figma_styles.json.
  5. Kliknij Dalej. Zobaczysz podgląd pakietów UI pliku.
  6. Kliknij Utwórz. Pakiety zostaną zaimportowane do projektu.

Okno importowania pakietów UI

  1. Utwórz projekt ponownie, a następnie otwórz plik switch/Switch.kt, aby wyświetlić wygenerowany kod.

Switch.kt (wygenerowano)

@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. Zwróć uwagę, że parametr backgroundColor jest ustawiony na pole MaterialTheme.colorScheme.surfaceVariant w obiekcie motywu tworzenia wiadomości.
  2. uruchomić projekt i włączyć tryb ciemny w emulatorze. Motyw został zastosowany prawidłowo, a błędy wizualne zostały poprawione.

6cf2aa19fabee292.png

9. Gratulacje

Gratulacje! Już wiesz, jak zintegrować usługę Relay z aplikacjami do tworzenia wiadomości.

Więcej informacji