با Relay و Jetpack Compose یک برنامه کامل بسازید

1. قبل از شروع

Relay ابزاری است که به تیم ها اجازه می دهد اجزای رابط کاربری را در Figma طراحی کرده و مستقیماً در پروژه های Jetpack Compose از آنها استفاده کنند. این نیاز به مشخصات طراحی خسته کننده و چرخه های QA را از بین می برد، که به تیم ها کمک می کند تا به سرعت رابط های کاربری عالی اندروید را ارائه دهند.

در این کد لبه، می‌آموزید که چگونه بسته‌های رابط کاربری Relay را در فرآیند توسعه Compose خود ادغام کنید. بر روی تکنیک‌های یکپارچه‌سازی تمرکز می‌کند، نه گردش کار انتها به انتها. برای آشنایی با گردش کار کلی برای Relay، به آموزش اولیه Relay مراجعه کنید.

پیش نیازها

  • تجربه اولیه با Compose. اگر قبلاً این کار را انجام نداده‌اید، آزمایشگاه کدهای مقدماتی Jetpack Compose را تکمیل کنید.
  • تجربه با نحو Kotlin.

چیزی که یاد خواهید گرفت

  • نحوه وارد کردن بسته های رابط کاربری
  • نحوه ادغام بسته های UI با ناوبری و معماری داده.
  • نحوه بسته بندی بسته های UI با منطق کنترلر.
  • نحوه نگاشت استایل های Figma به موضوع Compose.
  • نحوه جایگزینی بسته های UI با قابلیت های موجود در کد تولید شده.

چیزی که خواهی ساخت

  • یک طراحی برنامه واقعی بر اساس بسته های Relay ارائه شده توسط یک طراح. این برنامه Reflect نام دارد، یک برنامه ردیابی روزانه که ذهن آگاهی و عادات خوب را ترویج می کند. این شامل مجموعه ای از ردیاب ها از انواع مختلف و رابط کاربری برای اضافه کردن و مدیریت آنها است. این برنامه شبیه تصویر زیر است:

برنامه تمام شده

آنچه شما نیاز دارید

2. راه اندازی شوید

کد را دریافت کنید

برای دریافت کد این کد لبه یکی از موارد زیر را انجام دهید:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • به مخزن relay-codelabs در GitHub بروید، شاخه مورد نظر را انتخاب کنید و سپس روی Code > Download zip کلیک کنید و فایل فشرده دانلود شده را باز کنید.

در هر صورت، شاخه main حاوی کد شروع و شاخه end حاوی کد راه حل است.

افزونه Relay for Android Studio را نصب کنید

اگر قبلاً افزونه Relay for Android Studio را ندارید، این مراحل را دنبال کنید:

  1. در Android Studio، روی Settings > Plugins کلیک کنید.
  2. در کادر متن، Relay for Android Studio را وارد کنید.
  3. در افزونه ای که در نتایج جستجو ظاهر می شود، روی نصب کلیک کنید.

تنظیمات افزونه اندروید استودیو

  1. اگر گفتگوی یادداشت حریم خصوصی افزونه های شخص ثالث را مشاهده کردید، روی پذیرش کلیک کنید.
  2. روی OK > Restart کلیک کنید.
  3. اگر گفتگوی تأیید خروج را مشاهده کردید، روی خروج کلیک کنید.

اندروید استودیو را به Figma متصل کنید

Relay بسته های UI را با API Figma بازیابی می کند. برای استفاده از آن، به یک حساب کاربری رایگان Figma و یک رمز دسترسی شخصی نیاز دارید، به همین دلیل آنها در بخش آنچه شما نیاز دارید فهرست شده‌اند.

اگر قبلاً Android Studio را به Figma متصل نکرده اید، مراحل زیر را دنبال کنید:

  1. در حساب Figma خود، روی نماد نمایه خود در بالای صفحه کلیک کنید و تنظیمات را انتخاب کنید.
  2. در قسمت Personal access tokens ، توضیحاتی را برای توکن در کادر متن وارد کنید و سپس Enter (یا return در macOS) را فشار دهید. یک توکن تولید می شود.
  3. روی Copy this token کلیک کنید.

یک نشانه دسترسی تولید شده در Figma

  1. در Android Studio، Tools > Relay Settings را انتخاب کنید. یک گفتگوی تنظیمات رله ظاهر می شود.
  2. در کادر متنی Figma Access Token ، نشانه دسترسی را چسبانده و سپس روی OK کلیک کنید. محیط شما تنظیم شده است.

3. طراحی اپلیکیشن را مرور کنید

برای برنامه Reflect، ما با یک طراح کار کردیم تا به ما در تعریف رنگ، تایپوگرافی، طرح‌بندی و رفتار برنامه کمک کند. ما این طرح ها را مطابق با قراردادهای طراحی متریال 3 ایجاد کردیم تا برنامه به طور یکپارچه با مؤلفه ها و مضامین متریال کار کند.

صفحه اصلی را مرور کنید

صفحه اصلی لیستی از ردیاب های تعریف شده توسط کاربر را نمایش می دهد. همچنین هزینه هایی را برای تغییر روز فعال و ایجاد ردیاب های دیگر فراهم می کند.

صفحه اصلی

در Figma، طراح ما این صفحه را به چندین مؤلفه تقسیم کرد، APIهای آنها را تعریف کرد و آنها را با پلاگین Relay for Figma بسته بندی کرد. پس از بسته بندی این اجزا، می توانید آنها را به پروژه Android Studio خود وارد کنید.

جزء صفحه اصلی

صفحه افزودن/ویرایش را مرور کنید

صفحه افزودن/ویرایش به کاربران امکان می دهد ردیاب ها را اضافه یا ویرایش کنند. فرم نمایش داده شده بر اساس نوع ردیاب کمی متفاوت است.

صفحه افزودن/ویرایش

به طور مشابه، این صفحه نمایش به اجزای مختلف بسته بندی شده تقسیم می شود.

افزودن/ویرایش اجزای صفحه نمایش

موضوع را مرور کنید

رنگ‌ها و تایپوگرافی برای این طرح به‌عنوان سبک‌های Figma بر اساس نام نشانه‌های Material Design 3 پیاده‌سازی شده‌اند. این کار تعامل بهتری با مضامین Compose و اجزای Material فراهم می کند.

سبک های فیگما

4. بسته های رابط کاربری را وارد کنید

قبل از اینکه بتوانید بسته های UI را به پروژه خود وارد کنید، باید منبع طراحی را در Figma آپلود کنید.

برای دریافت لینک منبع Figma مراحل زیر را دنبال کنید:

  1. در Figma روی Import file کلیک کنید و سپس فایل ReflectDesign.fig موجود در پوشه پروژه CompleteAppCodelab را انتخاب کنید.
  2. روی فایل کلیک راست کرده و گزینه Copy link را انتخاب کنید. در بخش بعدی به آن نیاز دارید.

88afd168463bf7e5.png

بسته های UI را به پروژه وارد کنید

  1. در Android Studio، پروژه ./CompleteAppCodelab را باز کنید.
  2. روی File > New > Import UI Packages کلیک کنید. یک گفتگوی Import UI Packages ظاهر می شود.
  3. در کادر متنی URL منبع Figma ، نشانی اینترنتی را که در بخش قبل کپی کردید، قرار دهید.

f75d0c3e17b6f75.png

  1. در کادر نوشتاری طرح زمینه برنامه ، com.google.relay.example.reflect.ui.theme.ReflectTheme را وارد کنید . این تضمین می کند که پیش نمایش های تولید شده از تم سفارشی استفاده می کنند.
  2. روی Next کلیک کنید. پیش نمایشی از بسته های رابط کاربری فایل را مشاهده می کنید.
  3. روی ایجاد کلیک کنید. بسته ها به پروژه شما وارد می شوند.
  4. به تب Project بروید و سپس روی آن کلیک کنید 2158ffa7379d2b2e.png فلش توسعه دهنده در کنار پوشه ui-packages .

پوشه ui-packages

  1. را کلیک کنید 2158ffa7379d2b2e.png فلش توسعه دهنده را در کنار یکی از پوشه های بسته قرار دهید و سپس متوجه شوید که حاوی یک فایل منبع JSON و وابستگی های دارایی است.
  2. فایل منبع JSON را باز کنید. ماژول Relay یک پیش نمایش از بسته و API آن را نمایش می دهد.

a6105146c4cfb47.png

کد بسازید و تولید کنید

  1. در بالای Android Studio، کلیک کنید b3bc77f3c78cac1b.png پروژه بسازید کد تولید شده برای هر بسته به پوشه java/com.google.relay.example.reflect اضافه می شود. ترکیب‌های تولید شده حاوی تمام اطلاعات چیدمان و استایل طراحی Figma هستند.
  2. فایل com/google/relay/example/reflect/range/Range.kt را باز کنید.
  3. توجه داشته باشید که پیش‌نمایش Compose برای هر تغییر مؤلفه ایجاد می‌شود. در صورت لزوم، بر روی Split کلیک کنید تا پنجره های کد و پیش نمایش را در کنار یکدیگر ببینید.

c0d21ab0622ad550.png

5. اجزاء را یکپارچه کنید

در این بخش، کدهای تولید شده برای ردیاب سوئیچ را با دقت بیشتری مشاهده می کنید.

طراحی برای ردیاب سوئیچ

  1. در Android Studio، فایل com/google/relay/example/reflect/switch/Switch.kt باز کنید.

Switch.kt (تولید شده)

/**
 * This composable was generated from the UI Package 'switch'.
 * Generated code; don't edit directly.
 */
@Composable
fun Switch(
    modifier: Modifier = Modifier,
    isChecked: Boolean = false,
    emoji: String = "",
    title: String = ""
) {
    TopLevel(modifier = modifier) {
        if (isChecked) {
            ActiveOverlay(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f)) {}
        }
        TopLevelSynth(modifier = Modifier.rowWeight(1.0f)) {
            Label(modifier = Modifier.rowWeight(1.0f)) {
                Emoji(emoji = emoji)
                Title(
                    title = title,
                    modifier = Modifier.rowWeight(1.0f)
                )
            }
            Checkmark {
                if (isChecked) {
                    Icon()
                }
            }
        }
    }
}
  1. به موارد زیر توجه کنید:
  • تمام چیدمان و یک ظاهر طراحی شده از طرح Figma ایجاد شده است.
  • عناصر فرعی به اجزای قابل ترکیب جداگانه تقسیم می شوند.
  • پیش نمایش های قابل ترکیب برای همه تغییرات طراحی ایجاد می شود.
  • رنگ ها و سبک های تایپوگرافی هاردکد هستند. بعدا اینو درست کن

ردیاب را وارد کنید

  1. در Android Studio، فایل java/com/google/relay/example/reflect/ui/components/TrackerControl.kt باز کنید. این فایل داده ها و منطق تعامل را در اختیار ردیاب های عادت قرار می دهد.
  2. برنامه را در شبیه ساز بسازید و اجرا کنید. در حال حاضر، این کامپوننت داده های خام را از مدل ردیاب خروجی می دهد.

5d56f8a7065066b7.png

  1. بسته com.google.relay.example.reflect.switch.Switch را در فایل وارد کنید.
  2. Text(text = trackerData.tracker.toString()) را با یک بلوک when که در قسمت trackerData.tracker.type می چرخد، جایگزین کنید.
  3. در بدنه بلوک when ، تابع Switch() Composable را زمانی که نوع آن TrackerType.BOOLEAN است فراخوانی کنید.

کد شما باید به شکل زیر باشد:

TrackerControl.kt

// TODO: replace with Relay tracker components
when (trackerData.tracker.type) {
    TrackerType.BOOLEAN ->
        Switch(
          title = trackerData.tracker.name,
          emoji = trackerData.tracker.emoji
        )
    else ->
        Text(trackerData.tracker.toString())
}
  1. پروژه را بازسازی کنید. اکنون صفحه اصلی به درستی ردیاب Switch را با داده های زنده طراحی شده است.

4241e78b9f82075b.png

6. اضافه کردن حالت و تعامل

بسته های UI بدون تابعیت هستند. آنچه ارائه می شود نتیجه ساده پارامترهای ارسال شده است. اما برنامه های واقعی نیاز به تعامل و حالت دارند. کنترل‌کننده‌های تعامل را می‌توان مانند سایر پارامترها به ترکیب‌پذیرهای تولید شده منتقل کرد، اما وضعیتی را که آن دسته‌گرها دستکاری می‌کنند کجا حفظ می‌کنید؟ چگونه از انتقال یک کنترلر به هر نمونه جلوگیری می کنید؟ چگونه می توانید ترکیبات بسته ها را به مواد قابل استفاده مجدد تبدیل کنید؟ برای این موارد، توصیه می کنیم بسته های تولید شده خود را در یک تابع Composable سفارشی قرار دهید.

بسته های UI را در یک تابع Composable کنترلر بپیچید

بسته بندی بسته های رابط کاربری در یک کنترلر تابع Composable به شما امکان می دهد ارائه یا منطق تجاری را سفارشی کنید و در صورت لزوم وضعیت محلی را مدیریت کنید. طراحان همچنان می‌توانند بسته UI اصلی را در Figma به‌روزرسانی کنند، بدون اینکه از شما بخواهند کد wrapper را به‌روزرسانی کنند.

برای ایجاد یک کنترلر برای ردیاب سوئیچ، مراحل زیر را دنبال کنید:

  1. در Android Studio، فایل java/com/google/relay/example/reflect/ui/components/SwitchControl.kt باز کنید.
  2. در تابع SwitchControl() Composable ، پارامترهای زیر را ارسال کنید:
  • trackerData : یک شی TrackerData
  • 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 import را حذف کنید و سپس تابع Switch() را با فراخوانی تابع SwitchControl() جایگزین کنید.
  2. موارد ثابت شمارشگر TrackerType.RANGE و TrackerType.COUNT را اضافه کنید.

بلوک تکمیل شده when شبیه این قطعه کد است:

TrackerControl.kt

when (trackerData.tracker.type) {
    TrackerType.BOOLEAN ->
        SwitchControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
    TrackerType.RANGE ->
        RangeControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
    TrackerType.COUNT ->
        ValueControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
}
  1. پروژه را بازسازی کنید. اکنون می توانید ردیاب ها را نمایش داده و با آنها تعامل داشته باشید. صفحه اصلی کامل است.

b23b94f0034243d3.png

7. نقشه اجزای موجود

Relay به توسعه دهندگان این امکان را می دهد که کدهای تولید شده را با جایگزین کردن بسته های UI با قابلیت های موجود تنظیم کنند. این یک راه عالی برای خروجی اجزای خارج از جعبه یا حتی سیستم های طراحی سفارشی در کد شما است.

نقشه یک فیلد متنی

تصویر زیر طراحی مولفه Tracker Settings در گفتگوی افزودن/ویرایش ردیاب است:

طراحی برای مؤلفه تنظیمات سوئیچ

طراح ما از یک ReflectTextField در طراحی استفاده کرده است، که ما قبلاً یک پیاده سازی در کد ساخته شده در بالای فیلدهای متنی Material Design 3 داریم. Figma فیلدهای متنی را به صورت بومی پشتیبانی نمی‌کند، بنابراین کد پیش‌فرض تولید شده توسط Relay فقط شبیه طرح است. این یک کنترل عملکردی نیست.

برای آزمایش اجرای فعلی TrackerSettings :

  1. در اندروید استودیو، برنامه را در شبیه ساز بسازید و اجرا کنید.
  2. روی یک ردیف ردیاب به مدت طولانی فشار دهید و ویرایش را انتخاب کنید.
  3. روی قسمت Title text ضربه بزنید و توجه داشته باشید که به تعامل پاسخ نمی دهد.

برای جایگزینی پیاده سازی واقعی برای این عنصر، به دو چیز نیاز دارید: یک بسته UI فیلد متنی و یک فایل نقشه برداری . خوشبختانه طراح ما قبلاً اجزای سیستم طراحی ما را در Figma بسته بندی کرده و از یک جزء متنی در طراحی خود برای Tracker Settings استفاده کرده است. به‌طور پیش‌فرض، این بسته تودرتو به‌عنوان یک وابستگی تولید می‌شود، اما شما از نگاشت مؤلفه برای تعویض آن استفاده می‌کنید.

جزء Figma برای فیلد متنی با پلاگین Relay روکش شده

یک فایل نقشه برداری ایجاد کنید

پلاگین Relay for Android Studio یک میانبر برای ایجاد فایل های نگاشت کامپوننت فراهم می کند.

برای ایجاد یک فایل نقشه برداری، مراحل زیر را دنبال کنید:

  1. در Android Studio، روی بسته UI text_field کلیک راست کرده و سپس Generate mapping file را انتخاب کنید.

آیتم منوی زمینه فایل نقشه برداری را ایجاد کنید

  1. یک گفتگوی فایل نگاشت نمایش داده می شود. گزینه های زیر را وارد کنید:
  • در Target composable ، Use موجود composable را انتخاب کنید و com.google.relay.example.reflect.ui.components.ReflectTextField را وارد کنید.
  • در فایل تولید شده ، تیک Generate implement را بزنید و تیک Generate Compose Preview را بردارید

e776585c3b838b10.png

  1. روی Generate mapping file کلیک کنید. با این کار فایل نگاشت زیر تولید می شود:

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 ، تابع Composable TitleFieldStyleFilledStateEnabledTextConfigurationsInputText() ایجاد شده را پیدا کنید و توجه داشته باشید که شامل یک جزء ReflectTextField تولید شده است.

TrackerSettings.kt (تولید شده)

@Composable
fun TitleFieldStyleFilledStateEnabledTextConfigurationsInputText(
    onTitleChanged: (String) -> Unit,
    title: String,
    modifier: Modifier = Modifier
) {
    ReflectTextField(
        onChange = onTitleChanged,
        labelText = "Title",
        leadingIcon = "search",
        trailingIcon = "cancel",
        supportingText = "Supporting text",
        inputText = title,
        state = State.Enabled,
        textConfigurations = TextConfigurations.InputText,
        modifier = modifier.fillMaxWidth(1.0f).requiredHeight(56.0.dp)
    )
}
  1. پروژه را بازسازی کنید. اکنون می توانید با فیلدهای تنظیمات ردیاب تعامل داشته باشید. صفحه ویرایش کامل شده است.

8. نقشه برای نوشتن تم

به طور پیش فرض، Relay مقادیر تحت اللفظی رنگ ها و تایپوگرافی را تولید می کند. این امر دقت ترجمه را تضمین می‌کند، اما از استفاده مؤلفه‌ها از سیستم موضوعی Compose جلوگیری می‌کند. هنگامی که برنامه خود را در حالت تاریک مشاهده می کنید، این واضح است:

پیش نمایش صفحه اصلی با استفاده از حالت تاریک و نمایش رنگ های نادرست

مولفه ناوبری روز تقریباً نامرئی است و رنگ ها اشتباه هستند. برای رفع این مشکل، از ویژگی نگاشت سبک در Relay استفاده می‌کنید تا استایل‌های Figma را به توکن‌های موضوع Compose در کد تولید شده‌تان پیوند دهید. این امر هماهنگی بصری بین اجزای Relay و Material Design 3 را افزایش می دهد و پشتیبانی از حالت تاریک را فعال می کند.

1fac916db14929bb.png

یک فایل نگاشت سبک ایجاد کنید

  1. در Android Studio، به دایرکتوری src/main/ui-package-resources بروید و یک فهرست جدید به نام style-mappings ایجاد کنید. در آن دایرکتوری، یک فایل figma_styles.json ایجاد کنید که حاوی کد زیر است:

figma_styles.json

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

فایل‌های نگاشت تم با دو شی سطح بالا ساختار یافته‌اند: figma و compose . در داخل این اشیا، تعاریف رنگ و نوع از طریق نشانه‌های میانی بین هر دو محیط مرتبط می‌شوند. این به چندین سبک Figma اجازه می‌دهد تا به یک ورودی تم Compose نگاشت شوند، که زمانی مفید است که از تم‌های روشن و تاریک پشتیبانی می‌کنید.

  1. فایل نگاشت را مرور کنید، به خصوص اینکه چگونه ویژگی‌های تایپوگرافی را از Figma به آنچه Compose انتظار دارد، بازنگری می‌کند.

بسته های رابط کاربری را دوباره وارد کنید

پس از ایجاد یک فایل نگاشت، باید همه بسته‌های رابط کاربری را مجدداً به پروژه خود وارد کنید، زیرا تمام مقادیر سبک Figma پس از وارد کردن اولیه حذف شدند، زیرا فایل نگاشتی ارائه نشده بود.

برای وارد کردن مجدد بسته‌های رابط کاربری، این مراحل را دنبال کنید:

  1. در Android Studio، روی File > New > Import UI Packages کلیک کنید. یک گفتگوی Import UI Packages ظاهر می شود.
  2. در کادر متنی URL منبع Figma ، آدرس فایل منبع Figma را وارد کنید.
  3. چک باکس Translate Figma styles to Compose را انتخاب کنید.
  4. واردات پیکربندی سفارشی را انتخاب کنید. روی نماد پوشه کلیک کنید سپس فایلی را که ایجاد کرده اید انتخاب کنید: src/main/ui-package-resources/style-mappings/figma_styles.json .
  5. روی Next کلیک کنید. پیش نمایشی از بسته های رابط کاربری فایل را مشاهده می کنید.
  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 روی فیلد MaterialTheme.colorScheme.surfaceVariant در آبجکت Compose theme تنظیم می شود.
  2. پروژه را اجرا کنید و حالت تاریک را در شبیه ساز روشن کنید. موضوع به درستی اعمال می شود و اشکالات بصری رفع می شوند.

6cf2aa19fabee292.png

9. تبریک می گویم

تبریک می گویم! شما یاد گرفتید که چگونه Relay را در برنامه های Compose خود ادغام کنید!

بیشتر بدانید