ConstraintLayout
هو تنسيق يتيح لك وضع العناصر القابلة للتجميع بالنسبة إلى
العناصر القابلة للتجميع الأخرى على الشاشة. وهو بديل لاستخدام Row
وColumn
وBox
وعناصر التنسيق المخصّصة الأخرى المُدمجة المتعدّدة. ConstraintLayout
يكون مفيدًا عند تنفيذ تصاميم أكبر حجمًا مع متطلبات ALIGNED
أكثر تعقيدًا.
ننصحك باستخدام ConstraintLayout
في السيناريوهات التالية:
- لتجنُّب تداخل علامات
Column
وRow
متعددة من أجل وضع العناصر على الشاشة لتحسين إمكانية قراءة الرمز البرمجي. - لتحديد موضع العناصر القابلة للتجميع بالنسبة إلى العناصر القابلة للتجميع الأخرى أو لتحديد موضع العناصر القابلة للتجميع استنادًا إلى الإرشادات أو الحواجز أو السلاسل
في نظام "العرض"، كانت ConstraintLayout
هي الطريقة المُقترَحة لإنشاء تنسيقات كبيرة
ومعقدة، لأنّ التسلسل الهرمي للعرض المسطّح كان أفضل من ناحية الأداء مقارنةً بالتنسيقات
المُدمجة. ومع ذلك، لا يشكّل ذلك مصدر قلق في أداة "الإنشاء"، التي يمكنها
التعامل بكفاءة مع التسلسلات الهرميّة المعقدة للتخطيط.
بدء العمل باستخدام 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
في ميزة "الكتابة الذكية" من خلال واجهات برمجة التطبيقات في ملف عيّنات "الكتابة الذكية" التي تستخدِم ConstraintLayout
.
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون لغة JavaScript غير مفعّلة.
- التركيز في ميزة "إنشاء"
- Kotlin لـ Jetpack Compose
- أساسيات تنسيق الإنشاء