使用 Relay 和 Jetpack Compose 建構完整應用程式

1. 事前準備

Relay 是一種工具包,可讓團隊在 Figma 中設計 UI 元件,並直接在 Jetpack Compose 專案中使用這些元件。無須顧及繁瑣設計規格和品質管理週期,有助團隊快速提供優質的 Android UI。

在本程式碼研究室中,您將瞭解如何將 Relay UI 套件整合至 Compose 開發程序。這份文件著重於整合技巧,而非端對端工作流程。如要瞭解 Relay 的一般工作流程,請參閱 Relay 基本教學課程

必要條件

  • 有 Compose 的基本經驗。如果您尚未完成「Jetpack Compose 基本概念」程式碼研究室,請先完成該研究室。
  • 具備 Kotlin 語法經驗。

課程內容

  • 如何匯入 UI 套件。
  • 如何將 UI 套件與導覽和資料架構整合。
  • 如何使用控制器邏輯包裝 UI 套件。
  • 如何將 Figma 樣式對應至 Compose 主題。
  • 如何在產生的程式碼中,將 UI 套件替換為現有的可組合項。

建構項目

  • 根據設計人員提供的 Relay 套件,設計真實的應用程式。這款應用程式名為 Reflect,是一款每日追蹤應用程式,可鼓勵使用者培養正念和良好習慣。其中包含各種類型的追蹤器集合,以及用於新增及管理追蹤器的 UI。應用程式如下圖所示:

完成的應用程式

軟硬體需求

2. 做好準備

取得程式碼

如要取得本程式碼研究室的程式碼,請執行下列任一操作:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • 前往 GitHub 上的 relay-codelabs 存放區,選取所需分支,然後依序按一下「Code」>「Download zip」,並解壓縮下載的 ZIP 檔案。

無論是哪種情況,main 分支版本都會包含範例程式碼,end 分支版本則包含解決方案程式碼。

安裝 Relay for Android Studio 外掛程式

如果您還沒有 Relay for Android Studio 外掛程式,請按照下列步驟操作:

  1. 在 Android Studio 中,依序按一下「Settings」>「Plugins」
  2. 在文字方塊中輸入 Relay for Android Studio
  3. 在搜尋結果中顯示的擴充功能上,按一下「安裝」

Android Studio 外掛程式設定

  1. 如果畫面顯示「第三方外掛程式隱私權注意事項」對話方塊,請點選「接受」
  2. 依序按一下「確定」>「重新啟動」
  3. 如果畫面顯示「確認離開」對話方塊,請按一下「退出」

將 Android Studio 連結至 Figma

Relay 會使用 Figma API 擷取 UI 套件。如要使用這項功能,您需要免費的 Figma 帳戶個人存取權杖,因此這兩項項目會列在「所需工具」部分。

如果您尚未將 Android Studio 連結至 Figma,請按照下列步驟操作:

  1. 在 Figma 帳戶中,按一下頁面頂端的個人資料圖示,然後選取「Settings」
  2. 在「Personal access token」部分,在文字方塊中輸入權杖的說明,然後按下 Enter 鍵 (macOS 為 return 鍵)。系統會產生權杖。
  3. 按一下「Copy this token」

在 Figma 中產生的存取權杖

  1. 在 Android Studio 中,依序選取「Tools」>「Relay Settings」。系統隨即會顯示「Relay settings」對話方塊。
  2. 在「Figma Access Token」文字方塊中貼上存取權杖,然後按一下「確定」。環境已設定完畢。

3. 查看應用程式的設計

我們與設計人員合作設計了 Reflect 應用程式,包括選擇應用程式的顏色、字體排版、版面配置和行為。我們按照 Material Design 3 慣例建立這些設計,讓應用程式能與 Material 元件和主題完美搭配運作。

查看主畫面

主畫面會顯示使用者定義的追蹤器清單。並提供變更活動日和建立其他追蹤器的操作元素。

主畫面

在 Figma 中,設計師將這個畫面分割成多個元件,定義其 API,並使用 Relay for Figma 外掛程式封裝這些元件。這些元件套件完成後,您就可以將其匯入 Android Studio 專案。

主畫面元件

查看新增/編輯畫面

使用者可以透過新增/編輯畫面新增或編輯追蹤器。顯示的資料表單會因追蹤器類型而略有不同。

新增/編輯畫面

同樣地,這個畫面會分成多個已封裝的元件。

新增/編輯畫面元件

查看主題

這項設計的顏色和字體排版是以 Material Design 3 符記名稱做為 Figma 樣式實作。這可提供更佳的 Compose 主題和 Material 元件互通性。

Figma 樣式

4. 匯入 UI 套件

您必須先將設計來源上傳至 Figma,才能將 UI 套件匯入專案。

如要取得 Figma 來源的連結,請按照下列步驟操作:

  1. 在 Figma 中,按一下「Import file」,然後選取 CompleteAppCodelab 專案資料夾中的 ReflectDesign.fig 檔案。
  2. 在檔案上按一下滑鼠右鍵,然後選取「複製連結」。在下一節中會用到這項資訊。

88afd168463bf7e5.png

將 UI 套件匯入專案

  1. 在 Android Studio 中開啟 ./CompleteAppCodelab 專案。
  2. 依序點選「File」>「New」>「Import UI Packages」。畫面上會顯示「Import UI Packages」對話方塊。
  3. 在「Figma 來源網址」文字方塊中,貼上您在上一個部分複製的網址。

f75d0c3e17b6f75.png

  1. 在「應用程式主題」文字方塊中輸入 com.google.relay.example.reflect.ui.theme.ReflectTheme。這樣即可確保系統產生的預覽畫面會使用自訂主題。
  2. 按一下「繼續」,您會看到檔案的 UI 套件預覽畫面。
  3. 按一下「建立」,套件會匯入專案。
  4. 前往「Project」分頁,然後按一下 ui-packages 資料夾旁邊的 2158ffa7379d2b2e.png 展開箭頭。

ui-packages 資料夾

  1. 按一下其中一個套件資料夾旁的 2158ffa7379d2b2e.png 展開箭頭,然後注意該資料夾包含 JSON 來源檔案和資產依附元件。
  2. 開啟 JSON 來源檔案。Relay 模組會顯示套件及其 API 的預覽畫面。

a6105146c4cfb47.png

建構並產生程式碼

  1. 在 Android Studio 頂端,按一下 b3bc77f3c78cac1b.png「Make project」。每個套件的產生程式碼都會新增至 java/com.google.relay.example.reflect 資料夾。產生的可組合項包含 Figma 設計中的所有版面配置和樣式資訊。
  2. 開啟 com/google/relay/example/reflect/range/Range.kt 檔案。
  3. 請注意,系統會為每個元件變化版本建立 Compose 預覽畫面。視需要按一下「Split」,即可並排查看程式碼和預覽窗格。

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()) 替換成以 trackerData.tracker.type 欄位為樞紐的 when 區塊。
  3. when 區塊的主體中,當類型為 TrackerType.BOOLEAN 時,請呼叫 Switch() Composable 函式。

您的程式碼應如下所示:

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. 新增狀態和互動

UI 套件是無狀態的。所顯示的是傳入參數的簡單結果。但實際的應用程式需要互動和狀態。互動處理常式可像其他參數一樣傳遞至產生的可組合項,但您要將這些處理常式所處理的狀態儲存在何處?如何避免將相同的處理常式傳遞至每個例項?如何將套件的組合抽象化為可重複使用的可組合項?在這種情況下,建議您將產生的套件包裝在自訂 Composable 函式中。

在控制器 Composable 函式中包裝 UI 套件

將 UI 套件包裝在控制器 Composable 函式中,即可自訂呈現或商業邏輯,並視需要管理本機狀態。設計人員仍可自由更新 Figma 中的原始 UI 套件,無須更新包裝函式程式碼。

如要為 Switch 追蹤器建立控制器,請按照下列步驟操作:

  1. 在 Android Studio 中開啟 java/com/google/relay/example/reflect/ui/components/SwitchControl.kt 檔案。
  2. SwitchControl() Composable 函式中傳入下列參數:
  • trackerDataTrackerData 物件
  • modifier:裝飾物件
  • onLongClick:互動回呼,可讓您長按追蹤器進行編輯和刪除
  1. 插入 Switch() 函式,並傳入 combinedClickable 修飾符,以便處理點按和長按事件。
  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.RANGETrackerType.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,將 UI 套件替換為現有的可組合項,藉此自訂產生的程式碼。這是在程式碼中輸出即用元件,甚至是自訂設計系統的絕佳方法。

對應文字欄位

下圖為「Add/edit tracker」對話方塊中的 Tracker Settings 元件設計:

切換設定元件的設計

我們的設計師在設計中使用了 ReflectTextField,我們已在 Material Design 3 文字欄位上方建構的程式碼中實作了該元素。Figma 不支援原生文字欄位,因此 Relay 產生的預設程式碼只會顯示設計樣式,並非功能控制項。

如要測試 TrackerSettings 目前的實作方式,請按照下列步驟操作:

  1. 在 Android Studio 中,在模擬器中建構並執行應用程式。
  2. 長按追蹤器資料列,然後選取「編輯」
  3. 輕觸 Title 文字欄位,並注意它不會回應互動。

如要替換此元素的實際實作項目,您需要兩個項目:文字欄位 UI 套件對應檔案。幸運的是,我們的設計師已在 Figma 中為設計系統元件進行封裝,並在 Tracker Settings 的設計中使用文字欄位元件。根據預設,這個巢狀套件會以依附元件產生,但您可以使用元件對應功能進行交換。

文字欄位的 Figma 元件,已疊加 Relay 外掛程式

建立對應檔案

Relay for Android Studio 外掛程式提供建立元件對應檔案的捷徑。

如要建立對應檔案,請按照下列步驟操作:

  1. 在 Android Studio 中,在 text_field UI 套件上按一下滑鼠右鍵,然後選取「Generate mapping file」

產生對應檔案內容選單項目

  1. 系統隨即會顯示對應檔案對話方塊。輸入下列選項:
  • 在「Target composable」中,選取「Use existing composable」,然後輸入 com.google.relay.example.reflect.ui.components.ReflectTextField
  • 在「Generated file」中,勾選「Generate implementation」並取消勾選「Generate Compose Preview」

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. 對應至 Compose 主題

根據預設,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"
      }
    }
  }
}

主題對應檔案的結構包含兩個頂層物件:figmacompose。在這些物件中,顏色和類型定義會透過中繼符號連結兩個環境。這樣一來,多個 Figma 樣式就能對應至單一 Compose 主題項目,這在您支援淺色和深色主題時相當實用。

  1. 查看對應檔案,特別是如何將 Figma 的字體排版屬性重新對應至 Compose 預期的屬性。

重新匯入 UI 套件

建立對應檔案後,您必須將所有 UI 套件重新匯入專案,因為在初次匯入時,系統會捨棄所有 Figma 樣式值,因為沒有提供對應檔案。

如要重新匯入 UI 套件,請按照下列步驟操作:

  1. 在 Android Studio 中,依序點選「File」>「New」>「Import UI Packages」。畫面上會顯示「Import UI Packages」對話方塊。
  2. 在「Figma 來源網址」文字方塊中,輸入 Figma 來源檔案的網址。
  3. 選取「將 Figma 樣式轉譯為 Compose 主題」核取方塊。
  4. 選取「匯入自訂設定」。按一下資料夾圖示,然後選取您剛建立的檔案:src/main/ui-package-resources/style-mappings/figma_styles.json
  5. 按一下「繼續」,您會看到檔案的 UI 套件預覽畫面。
  6. 按一下「建立」,套件會匯入專案。

「Import UI Packages」對話方塊

  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 參數設為 Compose 主題物件中的 MaterialTheme.colorScheme.surfaceVariant 欄位。
  2. 在模擬器中執行專案並開啟深色模式。主題已正確套用,視覺錯誤也已修正。

6cf2aa19fabee292.png

9. 恭喜

恭喜!您已瞭解如何將 Relay 整合至 Compose 應用程式!

瞭解詳情