1. قبل البدء
Relay هي مجموعة أدوات تتيح للفرق تصميم مكونات واجهة المستخدم في Figma واستخدامها مباشرةً في مشاريع Jetpack Compose. ويزيل هذا الإجراء الحاجة إلى مواصفات التصميم المملة ودورات تأكيد الجودة، ما يساعد الفِرق على تقديم واجهات مستخدم رائعة لنظام التشغيل Android بسرعة.
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية دمج حِزم واجهة مستخدم Relay في عملية تطوير Compose. ويركز على أساليب الدمج، وليس سير العمل من البداية إلى النهاية. للتعرّف على سير العمل العام في تطبيق Relay، يُرجى الاطّلاع على الدليل التعليمي الأساسي لتطبيق Relay.
المتطلبات الأساسية
- تجربة أساسية مع ميزة "إنشاء" إذا لم يسبق لك ذلك، أكمِل أساسيات Jetpack Compose في ورشة رموز المصدر.
- خبرة في بنية Kotlin
ما ستتعرّف عليه
- كيفية استيراد حِزم واجهة المستخدم
- كيفية دمج حِزم واجهة المستخدم مع بنية البيانات والتنقّل
- كيفية لف حزم واجهة المستخدم باستخدام منطق وحدة التحكّم
- كيفية ربط أنماط Figma بمظهر Compose
- كيفية استبدال حِزم واجهة المستخدم بعناصر قابلة للتجميع حالية في الرمز الذي تم إنشاؤه
التطبيق الذي ستصممه
- تصميم تطبيق واقعي يستند إلى حِزم Relay التي يقدّمها مصمّم يُطلق على التطبيق اسم Reflect، وهو تطبيق تتبُّع يومي يشجع على التأمل والاعتياد على العادات الجيدة. يحتوي على مجموعة من أجهزة التتبُّع بأنواع مختلفة وواجهة مستخدم لإضافتها وإدارتها. يظهر التطبيق على النحو الموضّح في الصورة التالية:
المتطلبات
- الإصدار Electric Eel من استوديو Android أو الإصدارات الأحدث
- حساب مجاني على Figma ورمز دخول شخصي
2. الإعداد
الحصول على الرمز
للحصول على رمز هذا الدليل التعليمي حول الرموز البرمجية، يمكنك اتّباع أحد الإجراءَين التاليَين:
- استنسِخ مستودع
relay-codelabs
من GitHub:
$ git clone https://github.com/googlecodelabs/relay-codelabs
- انتقِل إلى مستودع
relay-codelabs
على GitHub، واختَر الفرع المطلوب، ثم انقر على الرمز > تنزيل ملف zip وفك ضغط ملف zip الذي تم تنزيله.
في كلتا الحالتَين، يحتوي الفرع main
على الرمز المبدئي ويحتوي الفرع end
على رمز الحلّ.
تثبيت المكوّن الإضافي Relay for Android Studio
إذا لم يكن لديك المكوّن الإضافي Relay for Android Studio، اتّبِع الخطوات التالية:
- في Android Studio، انقر على الإعدادات > المكونات الإضافية.
- في مربّع النص، أدخِل
Relay for Android Studio
. - في الإضافة التي تظهر في نتائج البحث، انقر على تثبيت.
- إذا ظهر لك مربّع حوار ملاحظة الخصوصية بشأن الإضافات التابعة لجهات خارجية، انقر على قبول.
- انقر على حسنًا > إعادة التشغيل.
- إذا ظهر لك مربّع حوار تأكيد الخروج، انقر على خروج.
ربط "استوديو Android" بتطبيق Figma
يسترجع Relay حِزم واجهة المستخدم باستخدام واجهة برمجة التطبيقات Figma API. لاستخدامه، تحتاج إلى حساب مجاني على Figma ورمز أمان وصول شخصي، لذلك تم إدراجهما في قسم المتطلّبات.
إذا لم يسبق لك ربط Android Studio بتطبيق Figma، اتّبِع الخطوات التالية:
- في حسابك على Figma، انقر على رمز ملفك الشخصي في أعلى الصفحة واختَر الإعدادات.
- في قسم رموز الوصول الشخصية، أدخِل وصفًا للرمز المميّز في مربّع النص، ثم اضغط على
Enter
(أوreturn
على نظام التشغيل macOS). يتم إنشاء رمز مميّز. - انقر على نسخ هذا الرمز المميّز.
- في Android Studio، اختَر الأدوات > إعدادات الإعادة. يظهر مربّع حوار إعدادات التوسّط.
- في مربّع نص رمز دخول Figma، الصِق رمز الدخول ثم انقر على حسنًا. تم إعداد بيئتك.
3- مراجعة تصميم التطبيق
بالنسبة إلى تطبيق Reflect، تعاونّا مع مصمّم لمساعدتنا في تحديد لون التطبيق وأسلوب الخط وتنسيقه وسلوكه. لقد أنشأنا هذه التصاميم وفقًا لمعيار Material Design 3 لكي يعمل التطبيق بسلاسة مع مكوّنات وألوان Material Design.
مراجعة الشاشة الرئيسية
تعرض الشاشة الرئيسية قائمة بالمتتبّعين المحدّدين من قِبل المستخدم. وتوفّر أيضًا إمكانات لتغيير اليوم النشط وإنشاء أجهزة تتبُّع أخرى.
في Figma، قسم المصمّم هذه الشاشة إلى مكونات متعددة وحدّد واجهات برمجة التطبيقات الخاصة بها وحزّمها باستخدام مكوّن Relay الإضافي في Figma. بعد تجميع هذه المكوّنات، يمكنك استيرادها إلى مشروعك على Android Studio.
راجِع شاشة الإضافة/التعديل.
تتيح شاشة الإضافة/التعديل للمستخدمين إضافة أجهزة التتبُّع أو تعديلها. يختلف النموذج المعروض قليلاً استنادًا إلى نوع التتبُّع.
وبالمثل، يتم تقسيم هذه الشاشة إلى مكونات مُجمَّعة متعددة.
مراجعة المظهر
تم تنفيذ ألوان هذا التصميم وأسلوب الخط فيه على أنّهما أسلوبان في Figma استنادًا إلى أسماء الرموز في التصميم المتعدد الأبعاد 3. ويؤدي ذلك إلى تحسين إمكانية التشغيل التفاعلي مع مظاهر Compose ومكونات Material.
4. استيراد حِزم واجهة المستخدم
الحصول على رابط لمصدر Figma
قبل أن تتمكّن من استيراد حِزم واجهة المستخدم إلى مشروعك، عليك تحميل مصدر التصميم إلى Figma.
للحصول على رابط إلى مصدر Figma، اتّبِع الخطوات التالية:
- في Figma، انقر على استيراد ملف، ثم اختَر ملف
ReflectDesign.fig
المتوفّر في مجلد المشروعCompleteAppCodelab
. - انقر بزر الماوس الأيمن على الملف، ثم اختَر نسخ الرابط. ستحتاج إليه في القسم التالي.
استيراد حِزم واجهة المستخدم إلى المشروع
- في "استوديو Android"، افتح مشروع
./CompleteAppCodelab
. - انقر على ملف > جديد > استيراد حِزم واجهة المستخدم. يظهر مربّع حوار استيراد حِزم واجهة المستخدم.
- في مربّع نص عنوان URL لمصدر Figma، الصِق عنوان URL الذي نسخته في القسم السابق.
- في مربّع نص مظهر التطبيق، أدخِل
com.google.relay.example.reflect.ui.theme.ReflectTheme
. يضمن ذلك استخدام المظهر المخصّص في المعاينات التي يتم إنشاؤها. - انقر على التالي. ستظهر لك معاينة لحِزم واجهة المستخدم في الملف.
- انقر على إنشاء. يتم استيراد الحِزم إلى مشروعك.
- انتقِل إلى علامة التبويب المشروع، ثم انقر على سهم التوسيع
بجانب المجلد
ui-packages
.
- انقر على
سهم التوسيع بجانب أحد مجلدات الحِزم، ثم لاحظ أنّه يحتوي على
JSON
ملف مصدر ومواد عرض تعتمد عليه. - افتح ملف المصدر
JSON
. تعرض وحدة Relay معاينة للحزمة وواجهة برمجة التطبيقات الخاصة بها.
إنشاء الرمز البرمجي وإنشاؤه
- في أعلى "استوديو Android"، انقر على
إنشاء مشروع. تتم إضافة الرمز الذي تم إنشاؤه لكل حزمة إلى مجلد
java/com.google.relay.example.reflect
. تحتوي العناصر القابلة للتجميع التي تم إنشاؤها على جميع معلومات التنسيق والتصميم من تصميم Figma. - افتح ملف
com/google/relay/example/reflect/range/Range.kt
. - يُرجى العلم أنّه يتم إنشاء معاينات ميزة "الإنشاء" لكلّ صيغة مكوّن. إذا لزم الأمر، انقر على تقسيم حتى يظهر لك رمز المحتوى ولوحة المعاينة بجانب بعضهما.
5- دمج المكوّنات
في هذا القسم، يمكنك إلقاء نظرة عن كثب على الرمز الذي تم إنشاؤه لتتبُّع Switch.
- في 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()
}
}
}
}
}
- يُرجى مراعاة ما يلي:
- يتم إنشاء كل التصميم والتنسيق من تصميم Figma.
- يتم تقسيم العناصر الفرعية إلى عناصر قابلة للتجميع منفصلة.
- يتم إنشاء معاينات قابلة للتجميع لجميع صيغ التصميم.
- يتمّ ترميز أنماط الألوان وأسلوب الخط بشكلٍ ثابت. يمكنك حلّ هذه المشكلة لاحقًا.
إدراج جهاز التتبُّع
- في Android Studio، افتح ملف
java/com/google/relay/example/reflect/ui/components/TrackerControl.kt
. يقدّم هذا الملف بيانات ومنطق التفاعل إلى أدوات تتبُّع العادات. - أنشئ التطبيق وشغِّله في المحاكي. يُخرج هذا المكوّن حاليًا البيانات الأوّلية من طراز جهاز التتبُّع.
- استورِد حزمة
com.google.relay.example.reflect.switch.Switch
إلى الملف. - استبدِل
Text(text = trackerData.tracker.toString())
بوحدةwhen
تدور حول الحقلtrackerData.tracker.type
. - في نصّ العنصر
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())
}
- أعِد إنشاء المشروع. تعرض الصفحة الرئيسية الآن أداة تتبُّع التبديل بشكلٍ صحيح كما هو مصمّم باستخدام البيانات المباشرة.
6- إضافة الحالة والتفاعل
حِزم واجهة المستخدم لا تتضمّن حالة. ويتم عرض نتيجة بسيطة للمَعلمات التي تم تمريرها. أمّا التطبيقات الحقيقية، فتحتاج إلى التفاعل والحالة. يمكن تمرير عناصر معالجة التفاعل إلى العناصر المُجمَّعة التي تم إنشاؤها مثل أي مَعلمات أخرى، ولكن أين يتم الاحتفاظ بالحالة التي تتعامل معها عناصر المعالجة هذه؟ كيف يمكنك تجنُّب تمرير المعالِج نفسه إلى كل مثيل؟ كيف يمكنك تجميع مكونات الحِزم في مكونات قابلة لإعادة الاستخدام؟ في هذه الحالات، ننصحك بتغليف الحِزم التي تم إنشاؤها في دالة Composable
مخصّصة.
لفّ حزم واجهة المستخدم في دالة Composable
الخاصة بوحدة التحكّم
يتيح لك تضمين حِزم واجهة المستخدم في دالة Composable
الخاصة بعنصر التحكّم إمكانية تخصيص العرض أو منطق النشاط التجاري، وإدارة الحالة المحلية إذا لزم الأمر. سيظل بإمكان المصمّمين تعديل حِزمة واجهة المستخدم الأصلية في Figma بدون الحاجة إلى تعديل رمز الحزمة.
لإنشاء وحدة تحكّم لتتبُّع جهاز التبديل، اتّبِع الخطوات التالية:
- في Android Studio، افتح ملف
java/com/google/relay/example/reflect/ui/components/SwitchControl.kt
. - في دالة
SwitchControl()
Composable
، أدخِل المَعلمات التالية:
trackerData
: عنصرTrackerData
modifier
: عنصر زخرفي-
onLongClick
: دالة استدعاء للتفاعل لتفعيل الضغط مع الاستمرار على أجهزة التتبُّع من أجل التعديل والحذف
- أدخِل دالة
Switch()
وأدخِل مُعدِّلcombinedClickable
للتعامل مع النقر والضغط المطوّل. - تمرير القيم من عنصر
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)
}
- في ملف
TrackerControl.kt
، أزِل عملية الاستيرادSwitch
، ثم استبدِل الدالةSwitch()
باستدعاء الدالةSwitchControl()
. - أضِف حالات لثابتَي المُعدِّلَين
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 },
)
}
- أعِد إنشاء المشروع. يمكنك الآن عرض أجهزة التتبُّع والتفاعل معها. اكتملت الشاشة الرئيسية.
7- ربط المكوّنات الحالية
يتيح Relay للمطوّرين تخصيص الرمز الذي تم إنشاؤه من خلال استبدال حِزم واجهة المستخدم بعناصر قابلة للتجميع حالية. هذه طريقة رائعة لإخراج مكونات جاهزة أو حتى أنظمة تصميم مخصّصة في الرمز البرمجي.
ربط حقل نصي
تعرض الصورة التالية تصميم المكوّن Tracker Settings
في مربّع الحوار إضافة/تعديل خدمة تتبُّع:
استخدم المصمّم ReflectTextField
في التصميم، وهو رمز سبق أن نفّذناه في رمز تم إنشاؤه على حقول نص Material Design 3. لا تتيح Figma استخدام الحقول النصية بشكلٍ تلقائي، لذا فإنّ الرمز الافتراضي الذي يتم إنشاؤه بواسطة Relay يبدو مثل التصميم فقط، وليس عنصر تحكّم وظيفيًا.
لاختبار التنفيذ الحالي لميزة TrackerSettings
:
- في "استوديو Android"، أنشئ التطبيق وشغِّله في المحاكي.
- اضغط مع الاستمرار على صفّ جهاز التتبُّع واختَر تعديل.
- انقر على حقل النص
Title
وتلاحظ أنّه لا يستجيب للتفاعل.
لاستبدال التنفيذ الفعلي لهذا العنصر، تحتاج إلى شيئَين: حزمة واجهة مستخدم حقل نص وملف ربط. لحسن الحظ، سبق أن حزّم مصمّمنا مكونات نظام التصميم في Figma واستخدَم مكوّن حقل نصّ في تصميمه لتطبيق Tracker Settings
. يتم إنشاء هذه الحزمة المُدمجة تلقائيًا كتبعية، ولكن يمكنك استخدام ربط المكوّنات لتبديلها.
إنشاء ملف ربط
يقدّم المكوّن الإضافي Relay for Android Studio اختصارًا لإنشاء ملفات ربط المكوّنات.
لإنشاء ملف ربط، اتّبِع الخطوات التالية:
- في Android Studio، انقر بزر الماوس الأيمن على حزمة
text_field
واجهة المستخدم، ثم اختَر إنشاء ملف ربط.
- سيظهر مربّع حوار لملف الربط. أدخِل الخيارات التالية:
- في العنصر المستهدف المكوّن، اختَر استخدام عنصر مكوّن حالي وأدخِل
com.google.relay.example.reflect.ui.components.ReflectTextField
. - في الملف الذي تم إنشاؤه، ضَع علامة في المربّع بجانب إنشاء عملية التنفيذ وأزِل العلامة من المربّع بجانب إنشاء معاينة Compose.
- انقر على إنشاء ملف الربط. سيؤدي ذلك إلى إنشاء ملف الربط التالي:
text_field.json
{
"target": "ReflectTextField",
"package": "com.google.relay.example.reflect.ui.components",
"generateImplementation": true,
"generatePreviews": false,
}
تحدِّد ملفات تعيين المكوّنات حزمة وهدف فئة Compose، بالإضافة إلى مجموعة اختيارية من كائنات fieldMapping
. تتيح لك عمليات ربط الحقول هذه تحويل مَعلمات الحِزم إلى مَعلمات Compose المتوقّعة. في هذه الحالة، تكون واجهات برمجة التطبيقات متطابقة، لذا ما عليك سوى تحديد الفئة المستهدَفة.
- أعِد إنشاء المشروع.
- في ملف
trackersettings/
TrackerSettings.kt
، ابحث عن دالةTitleFieldStyleFilledStateEnabledTextConfigurationsInputText()
Composable التي تم إنشاؤها وتلاحظ أنّها تتضمّن مكوّن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)
)
}
- أعِد إنشاء المشروع. يمكنك الآن التفاعل مع حقول إعدادات جهاز التتبُّع. اكتملت شاشة التعديل.
8. الربط بمظاهر Compose
ينشئ Relay تلقائيًا قيمًا حرفية للألوان وأسلوب الخط. يضمن ذلك دقة الترجمة، ولكنه يمنع المكونات من استخدام نظام تخصيص المظهر في تطبيق "الكتابة". يظهر ذلك بوضوح عند عرض تطبيقك في الوضع الداكن:
مكوّن التنقّل اليومي غير مرئي تقريبًا والألوان غير صحيحة. لحلّ هذه المشكلة، يمكنك استخدام ميزة ربط الأنماط في Relay لربط أنماط Figma بعناصر Compose theme tokens في الرمز الذي تم إنشاؤه. ويؤدي ذلك إلى زيادة الاتساق المرئي بين تطبيق Relay ومكونات Material Design 3، كما يتيح تفعيل الوضع الداكن.
إنشاء ملف ربط الأنماط
- في "استوديو Android"، انتقِل إلى الدليل
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، وهو أمر مفيد عند توفير المظهرين الفاتح والداكن.
- راجِع ملف الربط، خاصةً كيفية إعادة ربط خصائص الطباعة من Figma بما يتوقّعه تطبيق Compose.
إعادة استيراد حِزم واجهة المستخدم
بعد إنشاء ملف ربط، عليك إعادة استيراد جميع حِزم واجهة المستخدم إلى مشروعك لأنّه تم تجاهل جميع قيم أسلوب Figma عند الاستيراد الأولي بسبب عدم توفّر ملف ربط.
لإعادة استيراد حِزم واجهة المستخدم، اتّبِع الخطوات التالية:
- في Android Studio، انقر على ملف > جديد > استيراد حِزم واجهة المستخدم. يظهر مربّع حوار استيراد حِزم واجهة المستخدم.
- في مربّع نص عنوان URL لمصدر Figma، أدخِل عنوان URL لملف المصدر في Figma.
- ضَع علامة في مربّع الاختيار ترجمة أنماط Figma إلى مظهر Compose.
- اختَر استيراد الإعدادات المخصّصة. انقر على رمز المجلد، ثم اختَر الملف الذي أنشأته للتو:
src/main/ui-package-resources/style-mappings/figma_styles.json
. - انقر على التالي. ستظهر لك معاينة لحِزم واجهة المستخدم في الملف.
- انقر على إنشاء. يتم استيراد الحِزم إلى مشروعك.
- أعِد إنشاء مشروعك ثم افتح ملف
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)
)
}
- لاحظ كيف تم ضبط المَعلمة
backgroundColor
على الحقلMaterialTheme.colorScheme.surfaceVariant
في كائن موضوع Compose. - شغِّل المشروع وفعِّل الوضع الداكن في المحاكي. تم تطبيق المظهر بشكل صحيح وتم إصلاح الأخطاء المرئية.
9. تهانينا
تهانينا! لقد تعرّفت على كيفية دمج Relay في تطبيقات Compose.