ConstraintLayout طرحی است که به شما امکان می دهد کامپوزیشن ها را نسبت به سایر قابل ترکیب ها روی صفحه قرار دهید. این جایگزینی برای استفاده از چند ردیف Row , Column , Box و دیگر عناصر طرح بندی سفارشی است . ConstraintLayout هنگام اجرای طرحبندیهای بزرگتر با الزامات ترازبندی پیچیدهتر مفید است.
استفاده از ConstraintLayout را در سناریوهای زیر در نظر بگیرید:
- برای جلوگیری از تودرتو شدن چندین
ColumnوRowبرای تعیین موقعیت عناصر روی صفحه به منظور بهبود خوانایی کد. - قرار دادن کامپوزیشنها نسبت به سایر مواد ترکیبپذیر یا قرار دادن آنها بر اساس دستورالعملها، موانع یا زنجیرهها.
در سیستم View، ConstraintLayout روش پیشنهادی برای ایجاد طرحبندیهای بزرگ و پیچیده بود، زیرا سلسله مراتب نمای مسطح برای عملکرد بهتر از نماهای تودرتو بود. با این حال، این یک نگرانی در Compose نیست، زیرا می تواند به طور موثر سلسله مراتب طرح بندی عمیق را مدیریت کند.
با ConstraintLayout شروع کنید
برای استفاده از ConstraintLayout در Compose، باید این وابستگی را در build.gradle خود اضافه کنید (علاوه بر تنظیم Compose ):
implementation "androidx.constraintlayout:constraintlayout-compose:$constraintlayout_compose_version"
ConstraintLayout در Compose به روش زیر با استفاده از یک DSL کار می کند:
- برای هر composable در
ConstraintLayoutبا استفاده ازcreateRefs()یاcreateRefFor()مراجع ایجاد کنید. - محدودیتها با استفاده از اصلاحکننده
constrainAs()ارائه میشوند، که مرجع را به عنوان پارامتر میگیرد و به شما امکان میدهد محدودیتهای آن را در بدنه لامبدا مشخص کنید. - محدودیت ها با استفاده از
linkTo()یا سایر روش های مفید مشخص می شوند. -
parentیک مرجع موجود است که می تواند برای تعیین محدودیت ها نسبت به خودConstraintLayoutcomposable استفاده شود.
در اینجا یک مثال از یک Composable با استفاده از 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 محدود می کند.

Button و یک Text قابل ترکیب که در یک ConstraintLayout به یکدیگر محدود شده اند.API جدا شده
در مثال ConstraintLayout ، محدودیتها به صورت خطی مشخص شدهاند، با یک اصلاحکننده در composable که روی آن اعمال میشوند. با این حال، موقعیتهایی وجود دارد که ترجیح داده میشود محدودیتها را از طرحبندیهایی که برای آنها اعمال میشود جدا کنیم. به عنوان مثال، ممکن است بخواهید محدودیت ها را بر اساس پیکربندی صفحه تغییر دهید یا بین دو مجموعه محدودیت متحرک کنید.
برای مواردی مانند این، می توانید از ConstraintLayout به روش دیگری استفاده کنید:
- یک
ConstraintSetبه عنوان پارامتر بهConstraintLayoutمنتقل کنید. - ارجاعات ایجاد شده در
ConstraintSetرا با استفاده از اصلاح کنندهlayoutIdبه composable ها اختصاص دهید.
@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 از APIهای موجود در نمونه های Compose که از ConstraintLayout استفاده می کنند بیشتر بیاموزید.