Xây dựng một ứng dụng hoàn chỉnh bằng Relay và Jetpack Compose

1. Trước khi bắt đầu

Relay (Chuyển tiếp) là một bộ công cụ cho phép các nhóm thiết kế thành phần giao diện người dùng trong Figma và sử dụng các thành phần đó trực tiếp trong các dự án Jetpack Compose. Công cụ này loại bỏ nhu cầu thực hiện các quy cách thiết kế tẻ nhạt và chu kỳ đảm bảo chất lượng, giúp các nhóm nhanh chóng phân phối giao diện người dùng Android tuyệt vời.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tích hợp Gói giao diện người dùng Chuyển tiếp vào quy trình phát triển Compose. Giải pháp này tập trung vào các kỹ thuật tích hợp chứ không phải quy trình làm việc toàn diện. Để tìm hiểu về quy trình chung cho Relay, hãy xem Hướng dẫn cơ bản về Relay.

Điều kiện tiên quyết

Kiến thức bạn sẽ học được

  • Cách nhập Gói giao diện người dùng.
  • Cách tích hợp Gói giao diện người dùng với điều hướng và cấu trúc dữ liệu.
  • Cách gói Gói giao diện người dùng bằng logic bộ điều khiển.
  • Cách liên kết kiểu Figma với giao diện Compose.
  • Cách thay thế Gói giao diện người dùng bằng thành phần kết hợp hiện có trong mã đã tạo.

Sản phẩm bạn sẽ tạo ra

  • Một thiết kế ứng dụng thực tế dựa trên các gói Relay do nhà thiết kế cung cấp. Ứng dụng này có tên là Reflect, một ứng dụng theo dõi hằng ngày giúp khuyến khích chánh niệm và thúc đẩy các thói quen tốt. Đây là một tập hợp gồm nhiều loại thiết bị theo dõi, cũng như giao diện người dùng để thêm và quản lý các thiết bị theo dõi đó. Ứng dụng sẽ có giao diện như hình sau:

Ứng dụng đã hoàn thiện

Bạn cần có

2. Bắt đầu thiết lập

Lấy mã

Để lấy mã cho lớp học lập trình này, hãy làm theo một trong những cách sau:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • Chuyển đến kho lưu trữ relay-codelabs trên GitHub, chọn nhánh mong muốn, sau đó nhấp vào Mã > Tải tệp zip xuống rồi giải nén tệp zip đã tải xuống.

Trong cả hai trường hợp, nhánh main chứa đoạn mã khởi đầu và nhánh end chứa đoạn mã giải pháp.

Cài đặt trình bổ trợ Relay for Android Studio (Chuyển tiếp cho Android Studio)

Nếu bạn chưa có trình bổ trợ Relay for Android Studio (Chuyển tiếp cho Android Studio), hãy làm theo các bước sau:

  1. Trong Android Studio, hãy nhấp vào Settings (Cài đặt) > Trình bổ trợ.
  2. Trong hộp văn bản, hãy nhập Relay for Android Studio.
  3. Trên tiện ích xuất hiện trong kết quả tìm kiếm, hãy nhấp vào Cài đặt.

Cài đặt trình bổ trợ Android Studio

  1. Nếu bạn thấy hộp thoại Ghi chú về quyền riêng tư khi sử dụng trình bổ trợ của bên thứ ba, hãy nhấp vào Chấp nhận.
  2. Nhấp vào OK > Khởi động lại.
  3. Nếu bạn thấy hộp thoại Xác nhận thoát, hãy nhấp vào Thoát.

Kết nối Android Studio với Figma

Relay truy xuất Gói giao diện người dùng bằng API Figma. Để sử dụng công cụ này, bạn cần có một tài khoản Figma miễn phímã truy cập cá nhân. Do đó, các yêu cầu này có trong phần Những gì bạn cần.

Nếu bạn chưa kết nối Android Studio với Figma, hãy làm theo các bước sau:

  1. Trong tài khoản Figma, hãy nhấp vào biểu tượng hồ sơ ở đầu trang rồi chọn Cài đặt.
  2. Trong phần Mã truy cập cá nhân, hãy nhập nội dung mô tả về mã thông báo vào hộp văn bản rồi nhấn Enter (hoặc return trên macOS). Một mã thông báo đã được tạo.
  3. Nhấp vào Copy this token (Sao chép mã thông báo này).

Mã truy cập được tạo trong Figma

  1. Trong Android Studio, chọn Tools (Công cụ) > Cài đặt Relay. Hộp thoại Relay settings (Cài đặt trình chuyển tiếp) xuất hiện.
  2. Trong hộp văn bản Figma Access Token, hãy dán mã truy cập rồi nhấp vào OK. Môi trường của bạn đã được thiết lập.

3. Xem xét thiết kế của ứng dụng

Đối với ứng dụng Reflect, chúng tôi đã làm việc với một nhà thiết kế nhằm giúp xác định màu sắc, kiểu chữ, bố cục và hành vi của ứng dụng. Chúng tôi đã tạo ra những thiết kế này theo quy ước Material Design 3 để ứng dụng hoạt động liền mạch với các thành phần và giao diện Material.

Xem màn hình chính

Màn hình chính hiện một danh sách thiết bị theo dõi do người dùng xác định. Thư viện này cũng cung cấp các thành phần cho phép thay đổi ngày hoạt động và tạo các trình theo dõi khác.

Màn hình chính

Trong Figma, nhà thiết kế của chúng tôi đã chia màn hình này thành nhiều thành phần, xác định API và đóng gói bằng trình bổ trợ Chuyển tiếp cho Figma. Sau khi các thành phần này được đóng gói, bạn có thể nhập chúng vào dự án Android Studio.

Thành phần màn hình chính

Xem lại màn hình thêm/chỉnh sửa

Màn hình thêm/chỉnh sửa cho phép người dùng thêm hoặc chỉnh sửa trình theo dõi. Biểu mẫu xuất hiện hơi khác tuỳ theo loại thiết bị theo dõi.

Màn hình thêm/chỉnh sửa

Tương tự, màn hình này được chia thành nhiều thành phần đóng gói.

Thêm/chỉnh sửa các thành phần màn hình

Xem xét giao diện

Màu sắc và kiểu chữ cho thiết kế này được triển khai dưới dạng kiểu Figma dựa trên tên mã thông báo Material Design 3. Điều này giúp cải thiện khả năng tương tác với các giao diện Compose và thành phần Material.

Kiểu Figma

4. Nhập Gói giao diện người dùng

Trước khi có thể nhập Gói giao diện người dùng vào dự án, bạn cần tải nguồn thiết kế lên Figma.

Để nhận đường liên kết đến nguồn Figma, hãy làm theo các bước sau:

  1. Trong Figma, hãy nhấp vào Import file (Nhập tệp) rồi chọn tệp ReflectDesign.fig có trong thư mục dự án CompleteAppCodelab.
  2. Nhấp chuột phải vào tệp rồi chọn Sao chép đường liên kết. Bạn cần mã này ở phần tiếp theo.

88afd168463bf7e5.pngs

Nhập Gói giao diện người dùng vào dự án

  1. Trong Android Studio, hãy mở dự án ./CompleteAppCodelab.
  2. Nhấp vào File > (Tệp >) Mới > Nhập Gói giao diện người dùng Hộp thoại Import UI Packages (Nhập gói giao diện người dùng) sẽ xuất hiện.
  3. Trong hộp văn bản URL nguồn Figma, hãy dán URL mà bạn đã sao chép trong phần trước.

f75d0c3e17b6f75.png

  1. Trong hộp văn bản App theme (Giao diện của ứng dụng), hãy nhập com.google.relay.example.reflect.ui.theme.ReflectTheme. Điều này đảm bảo rằng các bản xem trước được tạo sẽ sử dụng giao diện tuỳ chỉnh.
  2. Nhấp vào Tiếp theo. Bạn sẽ thấy bản xem trước Gói giao diện người dùng của tệp.
  3. Nhấp vào Tạo. Các gói được nhập vào dự án của bạn.
  4. Chuyển đến thẻ Project (Dự án), sau đó nhấp vào biểu tượng mũi tên mở rộng 2158ffa7379d2b2e.png.bên cạnh thư mục ui-packages.

Thư mục ui-packages

  1. Nhấp vào mũi tên mở rộng 2158ffa7379d2b2e.png. bên cạnh một trong các thư mục gói để lưu ý rằng thư mục đó chứa tệp nguồn JSON và các phần phụ thuộc thành phần.
  2. Mở tệp nguồn JSON. Mô-đun Relay cho thấy bản xem trước của gói và API của gói đó.

a6105146c4cfb47.png

Xây dựng và tạo mã

  1. Ở đầu Android Studio, hãy nhấp vào b3bc77f3c78cac1b.png Tạo dự án. Mã đã tạo cho mỗi gói sẽ được thêm vào thư mục java/com.google.relay.example.reflect. Các thành phần kết hợp được tạo chứa mọi thông tin về bố cục và kiểu từ thiết kế Figma.
  2. Mở tệp com/google/relay/example/reflect/range/Range.kt.
  3. Xin lưu ý rằng bản xem trước trong Compose được tạo cho từng biến thể thành phần. Nếu cần, hãy nhấp vào Split (Phân tách) để thấy mã và các ngăn xem trước nằm cạnh nhau.

c0d21ab0622ad550.png

5. Tích hợp các thành phần

Trong phần này, bạn sẽ xem xét kỹ hơn mã đã tạo cho Trình theo dõi nút chuyển.

Thiết kế của Vòng đeo tay theo dõi chuyển đổi

  1. Trong Android Studio, mở tệp com/google/relay/example/reflect/switch/Switch.kt.

Switch.kt (đã tạo)

/**
 * 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. Hãy lưu ý những điều sau:
  • Tất cả bố cụcđịnh kiểu từ thiết kế Figma đều được tạo.
  • Các phần tử phụ được chia thành các thành phần kết hợp riêng biệt.
  • Hệ thống tạo bản xem trước thành phần kết hợp cho mọi biến thể thiết kế.
  • Kiểu màu và kiểu chữ được cố định giá trị trong mã. Bạn khắc phục vấn đề này vào lúc khác.

Chèn thiết bị theo dõi

  1. Trong Android Studio, mở tệp java/com/google/relay/example/reflect/ui/components/TrackerControl.kt. Tệp này cung cấp dữ liệu và logic tương tác cho công cụ theo dõi thói quen.
  2. Tạo bản dựng và chạy ứng dụng trong trình mô phỏng. Hiện tại, thành phần này xuất dữ liệu thô từ mô hình trình theo dõi.

5d56f8a7065066b7.pngs

  1. Nhập gói com.google.relay.example.reflect.switch.Switch vào tệp.
  2. Thay thế Text(text = trackerData.tracker.toString()) bằng một khối when xoay vòng trên trường trackerData.tracker.type.
  3. Trong phần nội dung của khối when, hãy gọi hàm Switch() Composable khi kiểu dữ liệu là TrackerType.BOOLEAN.

Mã của bạn sẽ có dạng như sau:

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. Tạo lại dự án. Giờ đây, trang chủ hiển thị chính xác Trình theo dõi chuyển như được thiết kế với dữ liệu trực tiếp.

4241e78b9f82075b.pngS

6. Thêm trạng thái và tương tác

Gói giao diện người dùng không có trạng thái. Nội dung được hiển thị là kết quả đơn giản của các tham số được truyền vào. Tuy nhiên, các ứng dụng thực cần có sự tương tác và trạng thái. Bạn có thể truyền trình xử lý tương tác vào các thành phần kết hợp được tạo giống như mọi tham số khác, nhưng bạn có thể giữ trạng thái mà các trình xử lý đó thao tác ở đâu? Làm cách nào để bạn tránh truyền cùng một trình xử lý đến mọi thực thể? Làm cách nào để trừu tượng hoá cấu trúc của các gói thành các thành phần kết hợp có thể tái sử dụng? Đối với những trường hợp này, bạn nên gói các gói đã tạo trong một hàm Composable tuỳ chỉnh.

Gói gói giao diện người dùng trong hàm Composable của bộ điều khiển

Việc bao bọc Gói giao diện người dùng trong hàm Composable của bộ điều khiển cho phép bạn tuỳ chỉnh bản trình bày hoặc logic nghiệp vụ và quản lý trạng thái cục bộ (nếu cần). Nhà thiết kế vẫn có thể thoải mái cập nhật Gói giao diện người dùng ban đầu trong Figma mà không yêu cầu bạn cập nhật mã trình bao bọc.

Để tạo tay điều khiển cho Trình theo dõi công tắc, hãy làm theo các bước sau:

  1. Trong Android Studio, mở tệp java/com/google/relay/example/reflect/ui/components/SwitchControl.kt.
  2. Trong hàm SwitchControl() Composable, hãy truyền các tham số sau:
  • trackerData: một đối tượng TrackerData
  • modifier: đối tượng trang trí
  • onLongClick: lệnh gọi lại tương tác để cho phép nhấn và giữ trên trình theo dõi để chỉnh sửa và xoá
  1. Chèn một hàm Switch() rồi truyền vào đối tượng sửa đổi combinedClickable để xử lý thao tác nhấp chuột và nhấn và giữ.
  2. Truyền các giá trị từ đối tượng TrackerData vào hàm Switch(), bao gồm cả phương thức isToggled().

Hàm SwitchControl() hoàn chỉnh sẽ có dạng như đoạn mã sau:

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. Trong tệp TrackerControl.kt, hãy xoá lệnh nhập Switch, sau đó thay thế hàm Switch() bằng lệnh gọi đến hàm SwitchControl().
  2. Thêm các trường hợp cho hằng số enum TrackerType.RANGETrackerType.COUNT.

Khối when hoàn chỉnh sẽ có dạng như đoạn mã sau:

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. Tạo lại dự án. Giờ đây, bạn có thể hiển thị và tương tác với các thiết bị theo dõi. Màn hình chính đã hoàn tất.

b23b94f0034243d3.png

7. Liên kết các thành phần hiện có

Relay cho phép nhà phát triển tuỳ chỉnh mã được tạo bằng cách thay thế Gói giao diện người dùng bằng các thành phần kết hợp hiện có. Đây là một cách tuyệt vời để xuất ra các thành phần có sẵn hoặc thậm chí là các hệ thống thiết kế tuỳ chỉnh trong mã của bạn.

Liên kết trường văn bản

Hình ảnh sau đây là thiết kế cho thành phần Tracker Settings trong hộp thoại Add/edit tracker (Thêm/chỉnh sửa trình theo dõi):

Thiết kế cho thành phần Cài đặt công tắc

Nhà thiết kế của chúng tôi đã sử dụng ReflectTextField trong quá trình thiết kế. Chúng tôi đã triển khai mã nguồn dựa trên các trường văn bản Material Design 3. Figma vốn không hỗ trợ các trường văn bản, vì vậy, mã mặc định do Relay tạo chỉ có hình dáng như thiết kế; thì đây không phải là chức năng kiểm soát.

Cách kiểm thử cách triển khai hiện tại cho TrackerSettings:

  1. Trong Android Studio, hãy tạo và chạy ứng dụng trong trình mô phỏng.
  2. Nhấn và giữ trên một hàng của thiết bị theo dõi rồi chọn Chỉnh sửa.
  3. Nhấn vào trường văn bản Title và lưu ý rằng trường này sẽ không phản hồi với hành động tương tác.

Để thay thế phương thức triển khai thực tế cho phần tử này, bạn cần có 2 thứ: gói giao diện người dùng trường văn bảntệp ánh xạ. May mắn thay, nhà thiết kế của chúng tôi đã đóng gói các thành phần hệ thống thiết kế trong Figma và sử dụng thành phần trường văn bản trong thiết kế của Tracker Settings. Theo mặc định, gói lồng nhau này được tạo dưới dạng phần phụ thuộc, nhưng bạn sẽ sử dụng mục ánh xạ thành phần để hoán đổi.

Thành phần Figma cho trường văn bản có lớp phủ trình bổ trợ Relay (Chuyển tiếp)

Tạo tệp ánh xạ

Trình bổ trợ Relay for Android Studio (Chuyển tiếp cho Android Studio) cung cấp lối tắt để tạo các tệp ánh xạ thành phần.

Để tạo một tệp ánh xạ, hãy làm theo các bước sau:

  1. Trong Android Studio, hãy nhấp chuột phải vào gói giao diện người dùng text_field rồi chọn Generate Mapping file (Tạo tệp ánh xạ).

Tạo mục trong trình đơn theo bối cảnh của tệp ánh xạ

  1. Hộp thoại tệp ánh xạ sẽ hiển thị. Nhập các lựa chọn sau:
  • Trong Target composable (Thành phần kết hợp mục tiêu), hãy chọn Use existingcomposable (Sử dụng thành phần kết hợp hiện có) rồi nhập com.google.relay.example.reflect.ui.components.ReflectTextField
  • Trong Tệp đã tạo, hãy chọn Tạo bản triển khai rồi bỏ đánh dấu Tạo bản xem trước trong Compose

e776585c3b838b10.png

  1. Nhấp vào Tạo tệp ánh xạ. Thao tác này sẽ tạo tệp ánh xạ sau:

text_field.json

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

Các tệp ánh xạ thành phần sẽ xác định mục tiêu và gói của lớp Compose, cũng như một tập hợp các đối tượng fieldMapping không bắt buộc. Các liên kết trường này cho phép bạn biến đổi các tham số gói thành các tham số Compose dự kiến. Trong trường hợp này, các API giống hệt nhau, vì vậy, bạn chỉ cần chỉ định lớp mục tiêu.

  1. Tạo lại dự án.
  2. Trong tệp trackersettings/ TrackerSettings.kt, hãy tìm hàm có khả năng kết hợp TitleFieldStyleFilledStateEnabledTextConfigurationsInputText() đã tạo và lưu ý rằng hàm đó bao gồm một thành phần ReflectTextField đã tạo.

TrackerSettings.kt (đã tạo)

@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. Tạo lại dự án. Giờ đây, bạn có thể tương tác với các trường cài đặt vòng đeo tay theo dõi. Màn hình chỉnh sửa đã hoàn tất.

8. Liên kết với giao diện Compose

Theo mặc định, Relay tạo ra các giá trị cố định cho màu sắc và kiểu chữ. Điều này đảm bảo độ chính xác của bản dịch, nhưng ngăn các thành phần sử dụng hệ thống tuỳ chỉnh giao diện Compose. Điều này rất rõ ràng khi bạn xem ứng dụng ở chế độ tối:

Bản xem trước màn hình chính bằng chế độ tối và hiển thị màu sắc không chính xác

Thành phần điều hướng theo ngày gần như không nhìn thấy được và màu sắc không chính xác. Để khắc phục vấn đề này, bạn hãy sử dụng tính năng ánh xạ kiểu trong Relay để liên kết kiểu Figma với mã thông báo giao diện Compose trong mã đã tạo. Điều này giúp tăng tính nhất quán về mặt hình ảnh giữa các thành phần Relay và Material Design 3, đồng thời cho phép hỗ trợ chế độ tối.

1fac916db14929bb.png.

Tạo tệp ánh xạ kiểu

  1. Trong Android Studio, hãy chuyển đến thư mục src/main/ui-package-resources rồi tạo một thư mục mới có tên là style-mappings. Trong thư mục đó, hãy tạo một tệp figma_styles.json chứa mã sau:

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

Tệp ánh xạ giao diện có cấu trúc gồm 2 đối tượng cấp cao nhất: figmacompose. Bên trong các đối tượng này, việc định nghĩa màu sắc và kiểu được liên kết giữa cả hai môi trường thông qua mã thông báo trung gian. Điều này cho phép nhiều kiểu Figma ánh xạ đến một mục nhập giao diện Compose. Điều này rất hữu ích khi bạn hỗ trợ giao diện sáng và tối.

  1. Xem lại tệp ánh xạ, đặc biệt là cách tệp này ánh xạ lại các thuộc tính kiểu chữ trong Figma với những gì Compose mong đợi.

Nhập lại Gói giao diện người dùng

Sau khi tạo tệp ánh xạ, bạn cần nhập lại tất cả các Gói giao diện người dùng vào dự án của mình vì tất cả giá trị kiểu Figma đã bị loại bỏ trong lần nhập đầu tiên vì bạn chưa cung cấp tệp ánh xạ.

Để nhập lại Gói giao diện người dùng, hãy làm theo các bước sau:

  1. Trong Android Studio, hãy nhấp vào File > (Tệp >) Mới > Nhập Gói giao diện người dùng Hộp thoại Import UI Packages (Nhập gói giao diện người dùng) sẽ xuất hiện.
  2. Trong hộp văn bản URL nguồn Figma, hãy nhập URL của tệp nguồn Figma.
  3. Chọn hộp đánh dấu Dịch kiểu Figma sang giao diện Compose.
  4. Chọn Nhập cấu hình tuỳ chỉnh. Nhấp vào biểu tượng thư mục rồi chọn tệp bạn vừa tạo: src/main/ui-package-resources/style-mappings/figma_styles.json.
  5. Nhấp vào Tiếp theo. Bạn sẽ thấy bản xem trước Gói giao diện người dùng của tệp.
  6. Nhấp vào Tạo. Các gói được nhập vào dự án của bạn.

Hộp thoại Import UI Packages (Nhập Gói giao diện người dùng)

  1. Hãy tạo lại dự án rồi mở tệp switch/Switch.kt để xem mã đã tạo.

Switch.kt (đã tạo)

@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. Hãy lưu ý cách đặt tham số backgroundColor thành trường MaterialTheme.colorScheme.surfaceVariant trong đối tượng giao diện Compose.
  2. Chạy dự án và bật chế độ tối trong trình mô phỏng. Giao diện được áp dụng đúng cách và đã khắc phục các lỗi về hình ảnh.

6cf2aa19fabee292.pngs

9. Xin chúc mừng

Xin chúc mừng! Bạn đã tìm hiểu cách tích hợp Relay vào các ứng dụng Compose!

Tìm hiểu thêm