تسهِّل أداة Jetpack Compose تصميم واجهة المستخدم في تطبيقك وإنشائها. تحوِّل دالة Compose الحالة إلى عناصر واجهة مستخدِم، وذلك من خلال:
- تركيب العناصر
- تنسيق العناصر
- رسم العناصر
يركز هذا المستند على تنسيق العناصر، ويوضّح بعض الكتل البرمجية الإنشائية التي يوفّرها تطبيق Compose لمساعدتك في ترتيب عناصر واجهة المستخدم.
أهداف التنسيقات في ميزة "الإنشاء"
يهدف تنفيذ Jetpack Compose لنظام التنسيق إلى تحقيق غرضَين رئيسيَّين:
- الأداء العالي
- إمكانية كتابة تنسيقات مخصّصة بسهولة
أساسيات الدوالّ المركّبة
الدوالّ القابلة للتجميع هي الوحدة الأساسية لتطبيق Compose. الدالة القابلة للتركيب
هي دالة تُنشئ Unit
تصف جزءًا من واجهة المستخدم. تستخدِم الدالة
بعض المدخلات وتُنشئ ما يظهر على الشاشة. لمزيد من
المعلومات عن العناصر القابلة للتجميع، اطّلِع على مستندات نموذج Compose mental
model.
قد تُنشئ الدالة القابلة للتجميع عدة عناصر واجهة مستخدم. ومع ذلك، إذا لم تقدِّم إرشادات حول كيفية ترتيبها، قد يرتّب تطبيق "الإنشاء" العناصر بطريقة لا تعجبك. على سبيل المثال، تُنشئ هذه التعليمة البرمجية عنصرَين مكوّنَين من نص:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
في حال عدم تقديم إرشادات حول كيفية ترتيبها، تُكدِّس ميزة "الإنشاء" عناصر النص فوق بعضها، ما يجعلها غير قابلة للقراءة:
يوفّر تطبيق Compose مجموعة من التنسيقات الجاهزة للاستخدام لمساعدتك في ترتيب عناصر واجهة المستخدم، وتسهيل تحديد التنسيقات الخاصة بك الأكثر تخصصًا.
مكونات التنسيق العادي
في العديد من الحالات، يمكنك استخدام عناصر التنسيق العادي في ميزة "الإنشاء" فقط.
استخدِم رمز
Column
لوضع العناصر عموديًا على الشاشة.
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }
وبالمثل، استخدِم رمز
Row
لوضع العناصر أفقيًا على الشاشة. يتيح كل من Column
وRow
ضبط محاذاة العناصر التي يحتويان عليها.
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }
استخدِم Box
لوضع عناصر فوق بعضها. يتيح Box
أيضًا ضبط محاذاة محدّدة للعناصر التي يحتوي عليها.
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }
وغالبًا ما تكون هذه العناصر الأساسية هي كل ما تحتاج إليه. يمكنك كتابة دالة قابلة للتجميع من أجل دمج هذه التنسيقات في تنسيق أكثر تفصيلاً يناسب تطبيقك.
لضبط موضع العناصر الفرعية في Row
، اضبط وسيطات horizontalArrangement
و
verticalAlignment
. بالنسبة إلى Column
، اضبط المَعلمتَين verticalArrangement
و
horizontalAlignment
:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }
نموذج التنسيق
في نموذج التنسيق، يتم عرض شجرة واجهة المستخدم في تمريرة واحدة. يُطلب من كل عقدة أولاً قياس نفسها، ثم قياس أي عناصر ثانوية بشكل متكرر، مع تمرير قيود الحجم إلى أسفل الشجرة إلى العناصر الثانوية. بعد ذلك، يتم تحديد حجم العقد الورقية ووضعها، مع إعادة توجيه الأحجام التي تم حلّها وتعليمات مواضع الإعلانات إلى الشجرة.
بعبارة أخرى، يتم قياس طول الوالدَين قبل أطفالهما، ولكن يتم تحديد مقاساتهما ووضعهما بعد أطفالهما.
ضع في الاعتبار الدالة SearchResult
التالية.
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
تؤدي هذه الدالة إلى إنشاء شجرة واجهة المستخدم التالية.
SearchResult
Row
Image
Column
Text
Text
في مثال SearchResult
، يتّبع تخطيط شجرة واجهة المستخدم الترتيب التالي:
- يتمّ طلب قياس العقدة الجذر
Row
. - تطلب العقدة الجذر
Row
من العنصر الثانوي الأول،Image
، إجراء القياس. Image
هي عقدة ورقة (أي ليس لها أيّ عقد فرعية)، لذا فهي تُبلغ عن حجم وتُعرِض تعليمات موضع الإعلان.- تطلب العقدة الجذر
Row
من العنصر الثاني،Column
، إجراء القياس. - تطلب عقدة
Column
من العنصر الثانويText
الأول قياس القيمة. - عقدة
Text
الأولى هي عقدة ورقة، لذا فهي تُبلغ عن حجم وتُعيد توجيه تعليمات التثبيت. - تطلب عقدة
Column
من العقدة الفرعية الثانيةText
إجراء القياس. - عقدة
Text
الثانية هي عقدة ورقة، لذا فهي تُبلغ عن حجم وتُعيد توجيه تعليمات موضع الإعلان. - بعد أن قياس عقدة
Column
لأطفالها وتحديد حجمها ووضعها، يمكنها تحديد حجمها وموضعها. - بعد أن قياس العقدة الجذر
Row
لأطفالها وتحديد حجمها ووضعها، يمكنها تحديد حجمها ووضعها.
الأداء
يحقّق تطبيق Compose أداءً عاليًا من خلال قياس أداء الأطفال مرّة واحدة فقط. إنّ القياس في تمريرة واحدة يُحسِّن الأداء، ما يسمح لميزة "الإنشاء" بمعالجة أشجار واجهة المستخدم العميقة بكفاءة. إذا كان عنصرًا يقيس عنصرًا فرعيًا مرتين وكان هذا العنصر الفرعي يقيس كل عنصر فرعي مرتين وما إلى ذلك، ستتطلّب محاولة واحدة لعرض واجهة مستخدم كاملة بذل الكثير من الجهد، ما يجعل من الصعب الحفاظ على أداء تطبيقك.
إذا كان التنسيق يحتاج إلى قياسات متعددة لسبب ما، يوفّر تطبيق Compose نظامًا خاصًا، وهو القياسات الأساسية. يمكنك الاطّلاع على مزيد من المعلومات حول هذه الميزة في مقالة القياسات الأساسية في تنسيقات Compose.
بما أنّ القياس وموضع الإعلان مرحلتان فرعيتان مختلفتان من خطوة تنسيق الإعلان، يمكن تنفيذ أي تغييرات تؤثّر فقط في موضع الإعلانات، وليس في القياس، بشكل منفصل.
استخدام عوامل التعديل في تصاميمك
كما هو موضّح في مقالة عناصر تعديل الإنشاء، يمكنك استخدام
عناصر التعديل لتزيين العناصر القابلة للإنشاء أو تحسينها. إنّ عوامل التعديل ضرورية
لتخصيص التنسيق. على سبيل المثال، نربط هنا عدة عوامل تعديل
لتخصيص ArtistCard
:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }
في الرمز البرمجي أعلاه، لاحظ الدوالّ المعدِّلة المختلفة المستخدَمة معًا.
- ينشئ
clickable
تفاعلًا قابلاً للتجميع يستجيب لإدخال المستخدم ويعرض تموجًا. - تُستخدَم العلامة
padding
لوضع مساحة حول عنصر معيّن. - تؤدي القيمة
fillMaxWidth
إلى ملء العنصر القابل للتجميع بأكبر عرض تم منحه له من العنصر الرئيسي. - تحدّد
size()
العرض والارتفاع المفضّلَين للعنصر.
التنسيقات القابلة للتمرير
اطّلِع على مزيد من المعلومات حول التنسيقات القابلة للتقديم أو الإيقاف في مستندات إيماءات الكتابة.
بالنسبة إلى القوائم والقوائم غير المتزامنة، يمكنك الاطّلاع على مستندات إنشاء القوائم.
التنسيقات المتجاوبة
يجب تصميم التنسيق مع مراعاة مختلف اتجاهات الشاشة وأحجام أشكال الأجهزة. يوفّر تطبيق Compose تلقائيًا بعض الآليات ل تسهيل تكييف التنسيقات القابلة للتجميع مع إعدادات الشاشات المختلفة.
القيود
لمعرفة القيود الواردة من العنصر الرئيسي وتصميم التنسيق
وفقًا لذلك، يمكنك استخدام BoxWithConstraints
. يمكن العثور على قيود measuring
في نطاق دالة lambda للمحتوى. يمكنك استخدام قيود القياس هذه لإنشاء تنسيقات مختلفة لإعدادات الشاشة المختلفة:
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
التنسيقات المستندة إلى الشرائح
يوفّر Compose مجموعة كبيرة من العناصر القابلة للتجميع استنادًا إلى Material
Design مع الاعتماد على
androidx.compose.material:material
(المضمّن عند إنشاء
مشروع Compose في Android Studio) لتسهيل إنشاء واجهة المستخدم. تتوفّر عناصر مثل
Drawer
،
FloatingActionButton
،
وTopAppBar
.
تعتمد مكونات Material بشكل كبير على واجهات برمجة التطبيقات الخاصة بالعناصر، وهو نمط يوفّره Compose
لإضافة طبقة من التخصيص إلى العناصر القابلة للتجميع. تجعل هذه الطريقة المكوّنات أكثر مرونة، لأنّها تقبل عنصرًا فرعيًا يمكنه ضبط نفسه بدلاً من الحاجة إلى عرض كل مَعلمة إعداد للعنصر الفرعي.
تترك الفتحات مساحة فارغة في واجهة المستخدم ليملؤها المطوّر على النحو الذي يريده. على سبيل المثال، في ما يلي المربّعات التي يمكنك تخصيصها في
TopAppBar
:
تأخذ العناصر القابلة للتجميع عادةً دالة lambda قابلة للتجميع من النوع content
( content: @Composable
() -> Unit
). تعرض واجهات برمجة تطبيقات الفتحات عدّة مَعلمات content
لاستخدامات محدّدة.
على سبيل المثال، تتيح لك السمة TopAppBar
تقديم محتوى السمات title
navigationIcon
وactions
.
على سبيل المثال،
Scaffold
يتيح لك تنفيذ واجهة مستخدم باستخدام بنية التنسيق الأساسية لتصميم Material.
يوفّرScaffold
خانات لمكوّنات Material الأكثر شيوعًا ذات المستوى الأعلى،
مثل TopAppBar
،
BottomAppBar
،
FloatingActionButton
،
وDrawer
. باستخدام
Scaffold
، من السهل التأكّد من وضع هذه المكوّنات بشكلٍ صحيح
وعملها معًا بشكلٍ صحيح.
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون لغة JavaScript غير مفعّلة.
- إنشاء المُعدِّلات
- Kotlin لـ Jetpack Compose
- مكونات Material وتنسيقاتها