تسهّل مجموعة أدوات Jetpack Compose تصميم واجهة مستخدم تطبيقك وإنشائها. تحوّل أداة Compose الحالة إلى عناصر في واجهة المستخدم من خلال:
- تركيب العناصر
- تخطيط العناصر
- رسم العناصر
يركّز هذا المستند على تنسيق العناصر، ويشرح بعض الوحدات الأساسية التي يوفّرها Compose لمساعدتك في تنسيق عناصر في واجهة المستخدم.
أهداف التنسيقات في Compose
يهدف تنفيذ نظام التنسيق في Jetpack Compose إلى تحقيق هدفَين رئيسيَين:
- الأداء العالي
- إمكانية كتابة تنسيقات مخصّصة بسهولة
أساسيات الدوال المركّبة
الدوال المركّبة هي الوحدة الأساسية في Compose. الدالة المركّبة هي دالة تُصدر Unit يصف جزءًا من واجهة المستخدم. تستخدم الدالة بعض المدخلات وتنشئ ما يظهر على الشاشة. لمزيد من المعلومات حول الدوال المركّبة، يمكنك الاطّلاع على مستندات النموذج الذهني لـ Compose.
قد تُصدر الدالة المركّبة عدة عناصر في واجهة المستخدم. ومع ذلك، إذا لم تقدّم إرشادات حول كيفية ترتيبها، قد ترتّب Compose العناصر بطريقة لا تعجبك. على سبيل المثال، ينشئ هذا الرمز عنصري نص:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
بدون إرشادات حول كيفية ترتيبها، يكدّس Compose عناصر النص فوق بعضها البعض، ما يجعلها غير قابلة للقراءة:
توفّر أداة Compose مجموعة من التنسيقات الجاهزة للاستخدام لمساعدتك في ترتيب عناصر واجهة المستخدم، وتسهّل عليك تحديد تنسيقاتك الخاصة الأكثر تخصّصًا.
مكوّنات التنسيق العادية
في كثير من الحالات، يمكنك استخدام عناصر التنسيق العادية في 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 نظامًا خاصًا، وهو القياسات الجوهرية. يمكنك الاطّلاع على مزيد من المعلومات حول هذه الميزة في القياسات الأساسية في تنسيقات Compose.
بما أنّ القياس والموضع هما مرحلتان فرعيتان متميّزتان من مرحلة التنسيق، يمكن تنفيذ أي تغييرات تؤثر فقط في موضع العناصر، وليس القياس، بشكل منفصل.
استخدام المُعدِّلات في التنسيقات
As discussed in Compose modifiers, you can use
modifiers to decorate or augment your composables. تُعدّ المُعدِّلات ضرورية
لتخصيص التنسيق. على سبيل المثال، نربط هنا عدة معدِّلات
لتخصيص 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.
بالنسبة إلى القوائم والقوائم الكسولة، يمكنك الاطّلاع على مستندات قوائم Compose.
التنسيقات المتجاوبة
يجب تصميم التنسيق مع مراعاة اتجاهات الشاشة المختلفة وأحجام الأجهزة. توفّر أداة Compose بعض الآليات الجاهزة لتسهيل تكييف التنسيقات القابلة للإنشاء مع إعدادات الشاشة المختلفة.
القيود
لمعرفة القيود التي يفرضها العنصر الرئيسي وتصميم التنسيق وفقًا لذلك، يمكنك استخدام BoxWithConstraints. يمكن العثور على قيود القياس في نطاق دالة lambda للمحتوى. يمكنك استخدام قيود القياس هذه لإنشاء تخطيطات مختلفة لإعدادات الشاشة المختلفة:
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
التنسيقات المستندة إلى الخانات
توفّر أداة Compose مجموعة كبيرة من الدوال المركّبة المستندة إلى التصميم المتعدد الأبعاد مع اعتمادية androidx.compose.material:material (يتم تضمينها عند إنشاء مشروع Compose في "استوديو Android") لتسهيل إنشاء واجهة المستخدم. يتم توفير عناصر مثل
Drawer
وFloatingActionButton
وTopAppBar.
تستخدم مكوّنات Material واجهات برمجة التطبيقات الخاصة بالخانات بشكل كبير، وهو نمط يقدّمه Compose لإضافة طبقة من التخصيص فوق الدوال المركّبة. هذا النهج يجعل المكونات أكثر مرونة، لأنها تقبل عنصرًا فرعيًا يمكنه تكوين نفسه بدلاً من الاضطرار إلى الكشف عن كل معلمة تكوين للعنصر الفرعي.
تترك الفتحات مساحة فارغة في واجهة المستخدم ليملأها المطوّر كما يشاء. على سبيل المثال، إليك الخانات التي يمكنك تخصيصها في TopAppBar:
تستخدم الدوال المركّبة عادةً دالة lambda مركّبة من النوع content ( content: @Composable
() -> Unit). وتكشف واجهات برمجة التطبيقات الخاصة بالخانات عن مَعلمات content متعددة لاستخدامات محدّدة.
على سبيل المثال، يتيح لك TopAppBar تقديم المحتوى لـ title وnavigationIcon وactions.
على سبيل المثال،
Scaffold
يتيح لك تنفيذ واجهة مستخدم باستخدام بنية تخطيط التصميم المتعدد الأبعاد الأساسية.
Scaffoldيوفر فتحات لمكونات المواد ذات المستوى الأعلى الأكثر شيوعًا،
مثل TopAppBar،
BottomAppBar،
FloatingActionButton،
وDrawer. باستخدام
Scaffold، من السهل التأكد من وضع هذه المكونات بشكل صحيح
والعمل معًا بشكل صحيح.
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
التطبيقات المقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما يكون JavaScript غير مفعَّل
- معدِّلات Compose
- Kotlin لـ Jetpack Compose
- مكوّنات Material وتنسيقاتها