ConstraintLayout
هو تخطيط يتيح لك وضع عناصر قابلة للإنشاء بالنسبة إلى عناصر أخرى قابلة للإنشاء على الشاشة. وهي بديل لاستخدام عناصر Row
وColumn
وBox
وعناصر أخرى مخصّصة للتنسيق متعدّدة ومتداخلة. ConstraintLayout
تكون مفيدة عند تنفيذ تنسيقات أكبر تتضمّن متطلبات محاذاة أكثر تعقيدًا.
ننصحك باستخدام ConstraintLayout
في السيناريوهات التالية:
- لتجنُّب تضمين عدة علامات
Column
وRow
لتحديد موضع العناصر على الشاشة من أجل تحسين إمكانية قراءة الرمز. - لتحديد موضع العناصر القابلة للإنشاء بالنسبة إلى العناصر الأخرى القابلة للإنشاء أو لتحديد موضع العناصر القابلة للإنشاء استنادًا إلى الإرشادات أو الحواجز أو السلاسل
في نظام العرض، كانت السمة ConstraintLayout
هي الطريقة المقترَحة لإنشاء تنسيقات كبيرة ومعقّدة، لأنّ تسلسل العرض الهرمي المسطّح كان أفضل من حيث الأداء من العروض المتداخلة. ومع ذلك، لا يشكّل ذلك مشكلة في Compose، الذي يمكنه التعامل بكفاءة مع التسلسلات الهرمية المعقّدة للتصميم.
بدء مشاهدة ConstraintLayout
لاستخدام ConstraintLayout
في Compose، عليك إضافة هذه التبعية في build.gradle
(بالإضافة إلى إعداد Compose):
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
تعمل ConstraintLayout
في Compose بالطريقة التالية باستخدام
لغة خاصة بالمجال (DSL):
- أنشئ مراجعًا لكل عنصر قابل للإنشاء في
ConstraintLayout
باستخدامcreateRefs()
أوcreateRefFor()
- يتم توفير القيود باستخدام المعدِّل
constrainAs()
، الذي يأخذ المرجع كمعلَمة ويتيح لك تحديد قيوده في نص تعبير lambda. - يتم تحديد القيود باستخدام
linkTo()
أو طرق مفيدة أخرى. -
parent
هو مرجع حالي يمكن استخدامه لتحديد قيود على العنصر القابل للإنشاءConstraintLayout
نفسه.
في ما يلي مثال على عنصر قابل للإنشاء يستخدم ConstraintLayout
:
@Composable fun ConstraintLayoutContent() { ConstraintLayout { // Create references for the composables to constrain val (button, text) = createRefs() Button( onClick = { /* Do something */ }, // Assign reference "button" to the Button composable // and constrain it to the top of the ConstraintLayout modifier = Modifier.constrainAs(button) { top.linkTo(parent.top, margin = 16.dp) } ) { Text("Button") } // Assign reference "text" to the Text composable // and constrain it to the bottom of the Button composable Text( "Text", Modifier.constrainAs(text) { top.linkTo(button.bottom, margin = 16.dp) } ) } }
يقيد هذا الرمز الجزء العلوي من Button
بالعنصر الرئيسي مع هامش يبلغ 16.dp
، كما يقيد الجزء السفلي من Button
بالجزء السفلي من Text
مع هامش يبلغ 16.dp
.
Decoupled API
في مثال ConstraintLayout
، يتم تحديد القيود بشكل مضمّن، مع معدِّل في العنصر القابل للإنشاء الذي يتم تطبيقها عليه. ومع ذلك، هناك حالات يُفضَّل فيها فصل القيود عن التصاميم التي تنطبق عليها. على سبيل المثال، قد تحتاج إلى تغيير القيود استنادًا إلى إعدادات الشاشة، أو إنشاء رسوم متحركة بين مجموعتَي قيود.
في حالات مثل هذه، يمكنك استخدام ConstraintLayout
بطريقة مختلفة:
- مرِّر
ConstraintSet
كمَعلمة إلىConstraintLayout
. - يمكنك تعيين مراجع تم إنشاؤها في
ConstraintSet
إلى عناصر قابلة للإنشاء باستخدام المعدِّلlayoutId
.
@Composable fun DecoupledConstraintLayout() { BoxWithConstraints { val constraints = if (minWidth < 600.dp) { decoupledConstraints(margin = 16.dp) // Portrait constraints } else { decoupledConstraints(margin = 32.dp) // Landscape constraints } ConstraintLayout(constraints) { Button( onClick = { /* Do something */ }, modifier = Modifier.layoutId("button") ) { Text("Button") } Text("Text", Modifier.layoutId("text")) } } } private fun decoupledConstraints(margin: Dp): ConstraintSet { return ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") constrain(button) { top.linkTo(parent.top, margin = margin) } constrain(text) { top.linkTo(button.bottom, margin) } } }
بعد ذلك، عندما تحتاج إلى تغيير القيود، يمكنك تمرير ConstraintSet
مختلف.
مفاهيم ConstraintLayout
تحتوي ConstraintLayout
على مفاهيم مثل الإرشادات والحواجز والسلاسل
التي يمكن أن تساعد في تحديد موضع العناصر داخل Composable.
الإرشادات
الإرشادات هي أدوات مساعدة بصرية صغيرة لتصميم التنسيقات. يمكن ربط العناصر القابلة للإنشاء بإرشادات. تفيد الخطوط الإرشادية في تحديد موضع العناصر عند dp
أو percentage
معيّن داخل العنصر القابل للإنشاء الرئيسي.
هناك نوعان مختلفان من الخطوط الإرشادية، وهما الخطوط العمودية والأفقية. الخطان الأفقيان هما top
وbottom
، والخطان العموديان هما start
وend
.
ConstraintLayout { // Create guideline from the start of the parent at 10% the width of the Composable val startGuideline = createGuidelineFromStart(0.1f) // Create guideline from the end of the parent at 10% the width of the Composable val endGuideline = createGuidelineFromEnd(0.1f) // Create guideline from 16 dp from the top of the parent val topGuideline = createGuidelineFromTop(16.dp) // Create guideline from 16 dp from the bottom of the parent val bottomGuideline = createGuidelineFromBottom(16.dp) }
لإنشاء إرشادات، استخدِم createGuidelineFrom*
مع نوع الإرشادات المطلوب. يؤدي ذلك إلى إنشاء مرجع يمكن استخدامه في
الكتلة Modifier.constrainAs()
.
الحواجز
تشير الحواجز إلى عناصر متعددة قابلة للإنشاء لإنشاء خط إرشادي افتراضي استنادًا إلى أقصى عنصر واجهة مستخدم على الجانب المحدّد.
لإنشاء حاجز، استخدِم createTopBarrier()
(أو: createBottomBarrier()
،
createEndBarrier()
، createStartBarrier()
)، وقدِّم المراجع التي
يجب أن يتكوّن منها الحاجز.
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val topBarrier = createTopBarrier(button, text) } }
يمكن بعد ذلك استخدام الحاجز في أحد حقول Modifier.constrainAs()
.
السلاسل
توفّر السلاسل سلوكًا مشابهًا للمجموعات في محور واحد (أفقيًا أو رأسيًا). يمكن تقييد المحور الآخر بشكل مستقل.
لإنشاء سلسلة، استخدِم createVerticalChain
أو createHorizontalChain
:
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val verticalChain = createVerticalChain(button, text, chainStyle = ChainStyle.Spread) val horizontalChain = createHorizontalChain(button, text) } }
يمكن بعد ذلك استخدام السلسلة في الحظر Modifier.constrainAs()
.
يمكن ضبط سلسلة باستخدام ChainStyles
مختلفة تحدّد كيفية التعامل مع المساحة المحيطة بعنصر قابل للإنشاء، مثل:
ChainStyle.Spread
: يتم توزيع المساحة بالتساوي على جميع العناصر القابلة للإنشاء، بما في ذلك المساحة الحرة قبل العنصر الأول وبعد العنصر الأخير القابل للإنشاء.ChainStyle.SpreadInside
: يتم توزيع المساحة بالتساوي على جميع العناصر القابلة للإنشاء، بدون أي مساحة فارغة قبل العنصر القابل للإنشاء الأول أو بعد العنصر القابل للإنشاء الأخير.-
ChainStyle.Packed
: يتم توزيع المساحة قبل العنصر الأول القابل للإنشاء وبعد العنصر الأخير القابل للإنشاء، ويتم تجميع العناصر القابلة للإنشاء معًا بدون مسافة بينها.
مزيد من المعلومات
يمكنك الاطّلاع على مزيد من المعلومات حول ConstraintLayout
في Compose من خلال واجهات برمجة التطبيقات المستخدَمة في
أمثلة Compose التي تستخدم ConstraintLayout
.
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون JavaScript غير مفعّلة
- التركيز في "الإنشاء"
- Kotlin لـ Jetpack Compose
- أساسيات تصميم صفحة الإنشاء