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
في ميزة "الإنشاء" بالطريقة التالية باستخدام
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
وText
في أسفل Button
أيضًا باستخدام هامش مقداره
16.dp
.
واجهة برمجة التطبيقات التي تم فصلها
في مثال 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
على مفاهيم، مثل الإرشادات والحدود والسلاسل
التي يمكن أن تساعد في تحديد موضع العناصر داخل العنصر القابل للتجميع.
الإرشادات
الإرشادات هي مساعدات مرئية صغيرة لتصميم التنسيقات. يمكن تقييد
العناصر القابلة للإنشاء وفقًا لإرشادات. تكون الإرشادات مفيدة لوضع العناصر في 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
- أساسيات تنسيق الرسائل