ConstraintLayout هو تخطيط يتيح لك وضع عناصر قابلة للإنشاء بالنسبة إلى عناصر أخرى قابلة للإنشاء على الشاشة. وهي بديل لاستخدام عدة عناصر متداخلة من Row وColumn وBox وعناصر أخرى مخصّصة للتنسيق.
في نظام العرض، كانت ConstraintLayout هي الطريقة المقترَحة لإنشاء تنسيقات كبيرة ومعقّدة، لأنّ هيكلية طرق العرض المسطّحة كانت أفضل من حيث الأداء من العروض المتداخلة. ومع ذلك، لا يشكّل ذلك مشكلة في Compose، الذي يمكنه التعامل بكفاءة مع التسلسلات الهرمية المعقّدة للتصميم، لذا لا تكون ميزة ConstraintLayout مفيدة بالقدر نفسه.
بدء المشاهدة مع "ConstraintLayout"
لاستخدام ConstraintLayout في Compose، عليك إضافة هذه الاعتمادية في build.gradle (بالإضافة إلى إعداد Compose):
implementation "androidx.constraintlayout:constraintlayout-compose:$constraintlayout_compose_version"
تعمل 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.
Button ودالة مركّبة Text مقيّدان ببعضهما البعض في ConstraintLayout.
واجهة برمجة التطبيقات المنفصلة
في مثال 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: يتم توزيع المساحة قبل العنصر الأول القابل للإنشاء وبعد العنصر الأخير القابل للإنشاء، ويتم تجميع العناصر القابلة للإنشاء معًا بدون مسافة بينها.