Komplette App mit Relay und Jetpack Compose erstellen

1. Hinweis

Relay ist ein Toolkit, mit dem Teams UI-Komponenten in Figma entwerfen und direkt in Jetpack Compose-Projekten verwenden können. Sie macht mühsame Designspezifikationen und QA-Zyklen überflüssig, was Teams dabei hilft, schnell hervorragende Android-UIs zu liefern.

In diesem Codelab erfahren Sie, wie Sie Relay-UI-Pakete in Ihren Compose-Entwicklungsprozess einbinden. Der Schwerpunkt liegt auf Integrationstechniken, nicht auf dem End-to-End-Workflow. Allgemeine Informationen zum Workflow für Relay findest du in der einführenden Anleitung für Relay.

Voraussetzungen

  • Grundlegende Funktionen von Compose Wenn Sie das noch nicht getan haben, absolvieren Sie das Codelab Jetpack Compose – Grundlagen.
  • Erfahrung mit der Kotlin-Syntax

Aufgaben in diesem Lab

  • So importieren Sie UI-Pakete.
  • Wie Sie UI-Pakete in die Navigations- und Datenarchitektur einbinden.
  • UI-Pakete in Controllerlogik einbetten
  • Figma-Stile Ihrem Compose-Design zuordnen
  • So ersetzen Sie UI-Pakete durch vorhandene Composeables im generierten Code.

Umfang

  • Ein realistisches App-Design, das auf Relay-Paketen basiert, die von einem Designer bereitgestellt wurden. Die App heißt „Reflect“ und ist eine tägliche Tracking-App, die Achtsamkeit und gute Gewohnheiten fördert. Sie enthält eine Sammlung verschiedener Arten von Trackern und eine Benutzeroberfläche, über die sie hinzugefügt und verwaltet werden können. Die App sieht so aus:

Die fertige App

Voraussetzungen

2. Einrichten

Code abrufen

So rufen Sie den Code für dieses Codelab ab:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • Rufen Sie das relay-codelabs-Repository auf GitHub auf, wählen Sie den gewünschten Branch aus und klicken Sie dann auf Code > ZIP-Datei herunterladen. Entpacken Sie die heruntergeladene ZIP-Datei.

In beiden Fällen enthält der main-Zweig den Startcode und der end-Zweig den Lösungscode.

Relay for Android Studio-Plug-in installieren

Wenn Sie das Relay for Android Studio-Plug-in noch nicht haben, gehen Sie so vor:

  1. Klicken Sie in Android Studio auf Einstellungen > Plug-ins.
  2. Geben Sie in das Textfeld Relay for Android Studio ein.
  3. Klicken Sie bei der Erweiterung in den Suchergebnissen auf Installieren.

Einstellungen für Android Studio-Plug-ins

  1. Wenn das Dialogfeld Datenschutzhinweis für Drittanbieter-Plug-ins angezeigt wird, klicken Sie auf Akzeptieren.
  2. Klicken Sie auf OK > Neu starten.
  3. Wenn das Dialogfeld Beenden bestätigen angezeigt wird, klicken Sie auf Beenden.

Android Studio mit Figma verbinden

Relay ruft UI-Pakete mit der Figma API ab. Sie benötigen ein kostenloses Figma-Konto und ein persönliches Zugriffstoken. Daher sind sie im Abschnitt Erforderliche Voraussetzungen aufgeführt.

Wenn Sie Android Studio noch nicht mit Figma verbunden haben, gehen Sie so vor:

  1. Klicken Sie in Ihrem Figma-Konto oben auf der Seite auf Ihr Profilsymbol und wählen Sie Einstellungen aus.
  2. Geben Sie im Bereich Persönliche Zugriffstokens eine Beschreibung für das Token in das Textfeld ein und drücken Sie dann die Taste Enter (oder return unter macOS). Es wird ein Token generiert.
  3. Klicken Sie auf Dieses Token kopieren.

Ein in Figma generiertes Zugriffstoken

  1. Wählen Sie in Android Studio Tools > Relay-Einstellungen aus. Das Dialogfeld Weiterleitungseinstellungen wird angezeigt.
  2. Fügen Sie das Zugriffstoken in das Textfeld Figma-Zugriffstoken ein und klicken Sie auf OK. Damit ist die Umgebung eingerichtet.

3. Design der App prüfen

Für die App „Reflect“ haben wir mit einem Designer zusammengearbeitet, um die Farbe, Typografie, das Layout und das Verhalten der App zu definieren. Wir haben diese Designs gemäß den Material Design 3-Konventionen erstellt, damit die App nahtlos mit Material-Komponenten und -Themen funktioniert.

Startbildschirm ansehen

Auf dem Startbildschirm wird eine Liste der benutzerdefinierten Tracker angezeigt. Außerdem können Sie den aktiven Tag ändern und andere Tracker erstellen.

Startbildschirm

In Figma hat unser Designer diesen Bildschirm in mehrere Komponenten unterteilt, ihre APIs definiert und sie mit dem Relay for Figma-Plug-in verpackt. Nachdem diese Komponenten verpackt wurden, können Sie sie in Ihr Android Studio-Projekt importieren.

Startbildschirmkomponente

Bildschirm zum Hinzufügen/Bearbeiten

Auf dem Bildschirm „Hinzufügen/Bearbeiten“ können Nutzer Tracker hinzufügen oder bearbeiten. Das angezeigte Formular unterscheidet sich je nach Trackertyp geringfügig.

Der Bildschirm zum Hinzufügen/Bearbeiten

Auch dieser Bildschirm ist in mehrere verpackte Komponenten unterteilt.

Bildschirmkomponenten hinzufügen/bearbeiten

Design prüfen

Farben und Typografie für dieses Design sind als Figma-Stile implementiert, die auf den Tokennamen von Material Design 3 basieren. Dadurch wird die Interoperabilität mit Compose-Designs und Material Components verbessert.

Figma-Stile

4. UI-Pakete importieren

Bevor Sie UI-Pakete in Ihr Projekt importieren können, müssen Sie die Designquelle in Figma hochladen.

So rufen Sie den Link zur Figma-Quelle ab:

  1. Klicken Sie in Figma auf Datei importieren und wählen Sie die Datei ReflectDesign.fig aus dem Projektordner CompleteAppCodelab aus.
  2. Klicken Sie mit der rechten Maustaste auf die Datei und wählen Sie Link kopieren aus. Sie benötigen sie im nächsten Abschnitt.

88afd168463bf7e5.png

UI-Pakete in das Projekt importieren

  1. Öffnen Sie in Android Studio das Projekt ./CompleteAppCodelab.
  2. Klicken Sie auf Datei > Neu > UI-Pakete importieren. Das Dialogfeld UI-Pakete importieren wird angezeigt.
  3. Fügen Sie im Textfeld Figma-Quell-URL die URL ein, die Sie im vorherigen Abschnitt kopiert haben.

f75d0c3e17b6f75.png

  1. Geben Sie im Textfeld App-Design den Wert com.google.relay.example.reflect.ui.theme.ReflectTheme ein. So wird sichergestellt, dass für generierte Vorschauen das benutzerdefinierte Design verwendet wird.
  2. Klicken Sie auf Weiter. Sie sehen eine Vorschau der UI-Pakete der Datei.
  3. Klicken Sie auf Erstellen. Die Pakete werden in Ihr Projekt importiert.
  4. Rufen Sie den Tab Projekt auf und klicken Sie neben dem Ordner ui-packages auf den Maximierungspfeil 2158ffa7379d2b2e.png.

Ordner „ui-packages“

  1. Klicken Sie neben einem der Paketordner auf den 2158ffa7379d2b2e.png-Maximierungspfeil. Sie sehen dann, dass er eine JSON-Quelldatei und Asset-Abhängigkeiten enthält.
  2. Öffnen Sie die JSON-Quelldatei. Im Relay-Modul wird eine Vorschau des Pakets und seiner API angezeigt.

a6105146c4cfb47.png

Code erstellen und generieren

  1. Klicken Sie oben in Android Studio auf b3bc77f3c78cac1b.png Make project (Projekt erstellen). Der generierte Code für jedes Paket wird dem Ordner java/com.google.relay.example.reflect hinzugefügt. Die generierten Composeables enthalten alle Layout- und Stilinformationen aus dem Figma-Design.
  2. Öffnen Sie die Datei com/google/relay/example/reflect/range/Range.kt.
  3. Für jede Komponentenvariante werden Compose-Vorschauen erstellt. Klicken Sie bei Bedarf auf Splitten, damit der Code und die Vorschau nebeneinander angezeigt werden.

c0d21ab0622ad550.png

5. Komponenten einbinden

In diesem Abschnitt sehen Sie sich den generierten Code für den Switch-Tracker genauer an.

Das Design für den Switch-Tracker

  1. Öffnen Sie in Android Studio die Datei com/google/relay/example/reflect/switch/Switch.kt.

Switch.kt (generiert)

/**
 * 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. Beachten Sie Folgendes:
  • Das gesamte Layout und Styling aus dem Figma-Design wird generiert.
  • Unterelemente werden in separate Kompositionen unterteilt.
  • Für alle Designvarianten werden zusammensetzbare Vorschauen generiert.
  • Farb- und Typografiestile sind hartcodiert. Sie beheben das Problem später.

Tracker einsetzen

  1. Öffnen Sie in Android Studio die Datei java/com/google/relay/example/reflect/ui/components/TrackerControl.kt. Diese Datei enthält Daten und Interaktionslogik für Gewohnheits-Tracker.
  2. Erstellen Sie die App und führen Sie sie im Emulator aus. Derzeit gibt diese Komponente Rohdaten aus dem Trackermodell aus.

5d56f8a7065066b7.png

  1. Importieren Sie das com.google.relay.example.reflect.switch.Switch-Paket in die Datei.
  2. Ersetzen Sie Text(text = trackerData.tracker.toString()) durch einen when-Block, der sich um das Feld trackerData.tracker.type dreht.
  3. Rufen Sie im when-Block die Funktion Switch() Composable auf, wenn der Typ TrackerType.BOOLEAN ist.

Ihr Code sollte in etwa so aussehen:

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. Erstellen Sie das Projekt neu. Jetzt wird der Switch-Tracker auf der Startseite wie vorgesehen mit Live-Daten gerendert.

4241e78b9f82075b.png

6. Status und Interaktion hinzufügen

UI-Pakete sind zustandslos. Die Ausgabe ist ein einfaches Ergebnis der übergebenen Parameter. Echte Apps benötigen jedoch Interaktion und Status. Interaktions-Handler können wie alle anderen Parameter an generierte Composeables übergeben werden. Wo wird aber der Status gespeichert, der von diesen Handlern manipuliert wird? Wie vermeiden Sie es, jeder Instanz denselben Handler zu übergeben? Wie können Sie Zusammensetzungen von Paketen in wiederverwendbare Kompositionen abstrahieren? In diesen Fällen empfehlen wir, die generierten Pakete in eine benutzerdefinierte Composable-Funktion einzubetten.

UI-Pakete in einer Controller-Composable-Funktion einschließen

Wenn Sie UI-Pakete in einer Controller-Composable-Funktion einschließen, können Sie die Präsentation oder Geschäftslogik anpassen und bei Bedarf den lokalen Status verwalten. Designer können das ursprüngliche UI-Paket in Figma weiterhin aktualisieren, ohne dass Sie den Wrapper-Code aktualisieren müssen.

So erstellen Sie einen Controller für den Switch-Tracker:

  1. Öffnen Sie in Android Studio die Datei java/com/google/relay/example/reflect/ui/components/SwitchControl.kt.
  2. Übergeben Sie in der Funktion SwitchControl() Composable die folgenden Parameter:
  • trackerData: ein TrackerData-Objekt
  • modifier: ein Decorator-Objekt
  • onLongClick: einen Interaktions-Callback, um das lange Drücken auf Tracker zum Bearbeiten und Löschen zu aktivieren
  1. Fügen Sie eine Switch()-Funktion ein und übergeben Sie einen combinedClickable-Modifikator, um Klicks und langes Drücken zu verarbeiten.
  2. Übergeben Sie Werte aus dem TrackerData-Objekt an die Switch()-Funktion, einschließlich der isToggled()-Methode.

Die fertige SwitchControl()-Funktion sieht so aus:

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. Entfernen Sie in der Datei TrackerControl.kt den Import Switch und ersetzen Sie dann die Funktion Switch() durch einen Aufruf der Funktion SwitchControl().
  2. Fügen Sie Fälle für die Enumeratorkonstanten TrackerType.RANGE und TrackerType.COUNT hinzu.

Der fertige when-Block sieht dann so aus:

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. Erstellen Sie das Projekt neu. Sie können jetzt Tracker anzeigen und mit ihnen interagieren. Der Startbildschirm ist fertig.

b23b94f0034243d3.png

7. Vorhandene Komponenten zuordnen

Mit Relay können Entwickler generierten Code anpassen, indem sie UI-Pakete durch vorhandene Composeables ersetzen. Dies ist eine gute Möglichkeit, vorkonfigurierte Komponenten oder sogar benutzerdefinierte Designsysteme in Ihrem Code auszugeben.

Textfeld zuordnen

Das folgende Bild zeigt das Design für die Tracker Settings-Komponente im Dialogfeld Tracker hinzufügen/bearbeiten:

Design für die Komponente „Schaltereinstellungen“

Unser Designer hat im Design ein ReflectTextField verwendet, für das wir bereits eine Codeimplementierung haben, die auf Material Design 3-Textfeldern basiert. Figma unterstützt Textfelder nicht nativ. Daher sieht der von Relay generierte Standardcode nur aus wie das Design. Es ist kein funktionsfähiges Steuerelement.

So testen Sie die aktuelle Implementierung für TrackerSettings:

  1. Erstellen Sie die App in Android Studio und führen Sie sie im Emulator aus.
  2. Halten Sie eine Trackerzeile gedrückt und wählen Sie Bearbeiten aus.
  3. Tippen Sie auf das Textfeld Title. Es reagiert nicht auf Interaktionen.

Um die echte Implementierung für dieses Element zu ersetzen, benötigen Sie zwei Dinge: ein UI-Paket für Textfelder und eine Zuordnungsdatei. Glücklicherweise hat unser Designer die Komponenten unseres Designsystems bereits in Figma verpackt und in seinem Design für Tracker Settings eine Textfeldkomponente verwendet. Dieses verschachtelte Paket wird standardmäßig als Abhängigkeit generiert, Sie können es aber mithilfe der Komponentenzuordnung austauschen.

Figma-Komponente für Textfeld mit überlagertem Relay-Plug-in

Zuordnungsdatei erstellen

Das Relay for Android Studio-Plug-in bietet eine Verknüpfung zum Erstellen von Komponentenzuordnungsdateien.

So erstellen Sie eine Zuordnungsdatei:

  1. Klicken Sie in Android Studio mit der rechten Maustaste auf das UI-Paket text_field und wählen Sie dann Zuordnungsdatei generieren aus.

Kontextmenüelement „Zuordnungsdatei generieren“

  1. Das Dialogfeld „Zuordnungsdatei“ wird angezeigt. Geben Sie die folgenden Optionen ein:
  • Wählen Sie unter Ziel-Composeable die Option Vorhandenes Composeable verwenden aus und geben Sie com.google.relay.example.reflect.ui.components.ReflectTextField ein.
  • Setzen Sie unter Generierte Datei ein Häkchen bei Implementierung generieren und entfernen Sie das Häkchen bei Compose-Vorschau generieren.

e776585c3b838b10.png

  1. Klicken Sie auf Zuordnungsdatei generieren. Dadurch wird die folgende Zuordnungsdatei generiert:

text_field.json

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

In Komponentenzuordnungsdateien werden ein Compose-Klassenziel und ein ‑Paket sowie eine optionale Sammlung von fieldMapping-Objekten angegeben. Mit diesen Feldzuordnungen können Sie Paketparameter in die erwarteten Compose-Parameter umwandeln. In diesem Fall sind die APIs identisch, sodass Sie nur die Zielklasse angeben müssen.

  1. Erstellen Sie das Projekt neu.
  2. Suchen Sie in der Datei trackersettings/ TrackerSettings.kt nach der generierten TitleFieldStyleFilledStateEnabledTextConfigurationsInputText()-Komposable-Funktion und beachten Sie, dass sie eine generierte ReflectTextField-Komponente enthält.

TrackerSettings.kt (generiert)

@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. Erstellen Sie das Projekt neu. Sie können jetzt mit den Feldern für die Trackereinstellungen interagieren. Der Bearbeitungsbildschirm ist vollständig.

8. Zu Compose-Designs zuordnen

Standardmäßig generiert Relay Literalwerte für Farben und Typografie. Dadurch wird die Übersetzungsgenauigkeit sichergestellt, aber Komponenten können das Compose-Designsystem nicht verwenden. Das ist besonders im dunklen Modus der Fall:

Vorschau des Startbildschirms im dunklen Modus mit falschen Farben

Die Navigationskomponente für den Tag ist fast unsichtbar und die Farben sind falsch. Um das Problem zu beheben, können Sie in Relay die Funktion zum Stil-Mapping verwenden, um Figma-Stile mit Compose-Themen-Tokens in Ihrem generierten Code zu verknüpfen. Dadurch wird die visuelle Einheitlichkeit zwischen Relay und Material Design 3-Komponenten erhöht und der Dunkelmodus unterstützt.

1fac916db14929bb.png

Datei für Stilzuordnung erstellen

  1. Rufen Sie in Android Studio das Verzeichnis src/main/ui-package-resources auf und erstellen Sie ein neues Verzeichnis mit dem Namen style-mappings. Erstellen Sie in diesem Verzeichnis eine figma_styles.json-Datei mit dem folgenden Code:

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

Themenzuordnungsdateien sind mit zwei übergeordneten Objekten strukturiert: figma und compose. Innerhalb dieser Objekte sind Farb- und Typdefinitionen über Zwischen-Tokens zwischen beiden Umgebungen verknüpft. So können mehrere Figma-Stile einem einzigen Compose-Designelement zugeordnet werden. Das ist nützlich, wenn Sie sowohl ein helles als auch ein dunkles Design unterstützen.

  1. Sehen Sie sich die Zuordnungsdatei an, insbesondere die Zuordnung von Typografieeigenschaften aus Figma zu den von Compose erwarteten.

UI-Pakete noch einmal importieren

Nachdem Sie eine Zuordnungsdatei erstellt haben, müssen Sie alle UI-Pakete noch einmal in Ihr Projekt importieren, da alle Figma-Stilwerte beim ersten Import verworfen wurden, da keine Zuordnungsdatei angegeben wurde.

So importieren Sie UI-Pakete noch einmal:

  1. Klicken Sie in Android Studio auf Datei > Neu > UI-Pakete importieren. Das Dialogfeld UI-Pakete importieren wird angezeigt.
  2. Geben Sie in das Textfeld Figma-Quell-URL die URL der Figma-Quelldatei ein.
  3. Klicken Sie das Kästchen Figma-Stile in Compose-Design übertragen an.
  4. Wählen Sie Benutzerdefinierte Konfiguration importieren aus. Klicken Sie auf das Ordnersymbol und wählen Sie die Datei aus, die Sie gerade erstellt haben: src/main/ui-package-resources/style-mappings/figma_styles.json.
  5. Klicken Sie auf Weiter. Sie sehen eine Vorschau der UI-Pakete der Datei.
  6. Klicken Sie auf Erstellen. Die Pakete werden in Ihr Projekt importiert.

Das Dialogfeld „UI-Pakete importieren“

  1. Erstelle dein Projekt neu und öffne dann die Datei switch/Switch.kt, um den generierten Code anzusehen.

Switch.kt (generiert)

@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. Beachten Sie, dass der Parameter backgroundColor im Compose-Themenobjekt auf das Feld MaterialTheme.colorScheme.surfaceVariant festgelegt ist.
  2. Führen Sie das Projekt aus und aktivieren Sie im Emulator den dunklen Modus. Das Design wird korrekt angewendet und die visuellen Fehler sind behoben.

6cf2aa19fabee292.png

9. Glückwunsch

Glückwunsch! Sie haben gelernt, wie Sie Relay in Ihre Compose-Apps einbinden.

Weitere Informationen