في ميزة "الإنشاء"، يتم تمثيل عناصر واجهة المستخدم من خلال الوظائف القابلة للإنشاء التي تنبعث من جزء من واجهة المستخدم عند استدعاءها، والتي تتم إضافتها بعد ذلك إلى شجرة واجهة المستخدم التي يتم عرضها على الشاشة. ويتضمّن كل عنصر في واجهة المستخدم عنصرًا رئيسيًا واحدًا وربما العديد من العناصر الثانوية. ويتوفر كل عنصر أيضًا داخل العنصر الرئيسي المحدَّد كموضع (x وy) وحجم
محدَّد على أنه width
وheight
.
يحدد الوالدان القيود المفروضة على العناصر الفرعية. ويُطلب من العنصر
تحديد حجمه ضمن هذه القيود. تُقيِّد القيود الحد الأدنى والحد الأقصى width
للعنصر وheight
. إذا كان العنصر يحتوي على عناصر ثانوية، قد يقيس كل عنصر فرعي للمساعدة في تحديد حجمه. بعد أن يحدّد العنصر
حجمه ويُبلغ عنه، يصبح بإمكانه تحديد كيفية وضع عناصره
الثانوية مقارنةً بنفسها، كما هو موضّح بالتفصيل في إنشاء تنسيقات
مخصّصة.
تتألّف عملية التصميم لكل عقدة في شجرة واجهة المستخدم من ثلاث خطوات. يجب أن تستوفي كل عقدة ما يلي:
- قياس مستوى أي أطفال
- تحديد حجمه
- وضع أطفاله
استخدام النطاقات هو الذي يحدّد الحالات التي يمكنك فيها قياس أطفالك ووضعهم في الاعتبار. لا يمكن إجراء قياس إلا أثناء قياسات القياس والتنسيق، ولا يمكن وضع الطفل إلا بعد تمرير تنسيقه (فقط بعد قياسه). بسبب نطاقات الإنشاء، مثل MeasurementScope، وPlacementsScope، يتم فرض ذلك في وقت التجميع.
استخدام معدِّل التنسيق
يمكنك استخدام المُعدِّل "layout
" لتعديل كيفية قياس عنصر وتحديده. Layout
هي دالة lambda، وتتضمّن معلَماتها العنصر الذي يمكنك قياسه،
وتم تمريره على أنّه measurable
، والقيود التي تظهر على الموقع قابلة للإنشاء، والتي يتم ضبطها على أنها
constraints
. يمكن أن يبدو مُعدِّل التنسيق المخصص على النحو التالي:
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
لنعرِض Text
على الشاشة ونتحكّم في المسافة من أعلى السطر إلى
سطر السطر الأول من النص. هذه هي بالضبط الطريقة التي ينفّذ بها معدِّل paddingFromBaseline
، ويتم تنفيذه هنا كمثال.
لإجراء ذلك، استخدِم المُعدِّل layout
لوضع العناصر القابلة للإنشاء يدويًا على الشاشة. إليك السلوك الذي تم فيه ضبط المساحة المتروكة في Text
الأعلى على 24.dp
:
إليك الرمز الذي ينتج عن ذلك التباعد:
fun Modifier.firstBaselineToTop( firstBaselineToTop: Dp ) = layout { measurable, constraints -> // Measure the composable val placeable = measurable.measure(constraints) // Check the composable has a first baseline check(placeable[FirstBaseline] != AlignmentLine.Unspecified) val firstBaseline = placeable[FirstBaseline] // Height of the composable with padding - first baseline val placeableY = firstBaselineToTop.roundToPx() - firstBaseline val height = placeable.height + placeableY layout(placeable.width, height) { // Where the composable gets placed placeable.placeRelative(0, placeableY) } }
إليك ما يحدث في هذا الرمز:
- في مَعلمة lambda في
measurable
، يمكنك قياس المعلَمةText
الممثَّلة بواسطة المَعلمة القابلة للقياس عن طريق استدعاءmeasurable.measure(constraints)
. - ويمكنك تحديد حجم العنصر القابل للإنشاء من خلال استدعاء الطريقة
layout(width, height)
التي توفّر دالة lambda المُستخدَمة لوضع العناصر الملفوفة. وفي هذه الحالة، تكون القيمة هي الارتفاع بين القاعدة المرجعية الأخيرة وأكبر مساحة متروكة. - يمكنك وضع العناصر الملفوفة على الشاشة من خلال الاتصال
placeable.place(x, y)
. إذا لم يتم وضع العناصر الملفوفة، لن تكون مرئية. يتوافقy
الموضع مع المساحة المتروكة العليا، وهي موضع الخط المرجعي الأول للنص.
للتأكد من أنّ هذه العملية تعمل على النحو المتوقّع، استخدِم أداة التعديل هذه على Text
:
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }
إنشاء تنسيقات مخصّصة
لا يغيّر معدِّل layout
سوى المكالمات القابلة للإنشاء. لقياس وتعديل عدة تركيبات، يمكنك استخدام السمة Layout
القابلة للإنشاء. ويسمح لك ذلك القابل للإنشاء
بقياس الأطفال وتحديدهم يدويًا. تم تصميم جميع التنسيقات ذات المستوى الأعلى، مثل Column
وRow
، بشكل قابل للدمج مع Layout
.
لننشئ إصدارًا أساسيًا من Column
. تتبع معظم التنسيقات المخصصة هذا النمط:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
على غرار المُعدِّل layout
، تمثل measurables
قائمة العناصر الثانوية التي يجب قياسها وconstraints
هي القيود المفروضة من العنصر الرئيسي.
باتّباع المنطق نفسه كما في السابق، يمكن تنفيذ MyBasicColumn
على النحو التالي:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
تخضع العناصر القابلة للإنشاء الفرعية للقيود Layout
(بدون قيود minHeight
) ويتم وضعها استنادًا إلى yPosition
للتركيبة السابقة.
في ما يلي كيفية استخدام الصيغة القابلة للإنشاء المخصّصة:
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }
اتجاه التنسيق
يمكنك تغيير اتجاه التنسيق للإنشاء من خلال تغيير مقطوعة
LocalLayoutDirection
المحلية.
في حال وضع عناصر قابلة للإنشاء يدويًا على الشاشة، تُعدّ LayoutDirection
جزءًا من LayoutScope
المعدِّل layout
أو Layout
القابل للإنشاء.
عند استخدام layoutDirection
، يمكنك وضع العناصر القابلة للإنشاء باستخدام place
. وعلى عكس الطريقة placeRelative
، لا تتغير place
بناءً على اتجاه التنسيق (من اليسار إلى اليمين أو من اليمين إلى اليسار).
التنسيقات المخصصة قيد الاستخدام
تعرَّف على مزيد من المعلومات عن التنسيقات والمعدِّلات في التنسيقات الأساسية في Compose، واطّلِع على كيفية استخدام التنسيقات المخصّصة في إنشاء النماذج التي تنشئ تنسيقات مخصّصة.
مزيد من المعلومات
لمعرفة المزيد من المعلومات عن التنسيقات المخصصة في ميزة "الإنشاء"، يُرجى الاطّلاع على المراجع الإضافية التالية.