تسهّل 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.
بما أنّ القياس وموضع العناصر هما مرحلتان فرعيتان منفصلتان من عملية تحديد موضع العناصر، يمكن تنفيذ أي تغييرات تؤثر فقط في موضع العناصر، وليس في القياس، بشكل منفصل.
استخدام أدوات التعديل في تخطيطاتك
كما هو موضّح في معدِّلات الإنشاء، يمكنك استخدام المعدِّلات لتزيين العناصر القابلة للإنشاء أو تحسينها. تُعدّ المعدّلات ضرورية لتخصيص التنسيق. على سبيل المثال، نربط هنا عدة معدِّلات
لتخصيص 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 غير مفعّلة
- معدِّلات الإنشاء
- Kotlin لـ Jetpack Compose
- مكوّنات وتنسيقات Material