ConstraintLayout چیدمانی است که به شما امکان میدهد عناصر ترکیبی را نسبتبه
عناصر ترکیبی دیگر در صفحه قرار دهید. این یک جایگزین برای استفاده از چندین عنصر چیدمان سفارشی
Row، Column، Box، و دیگر است.
در سیستم View، ConstraintLayout روش توصیهشده برای ایجاد چیدمانهای بزرگ و پیچیده بود، زیرا سلسلهمراتب نمای تخت برای عملکرد بهتر از نمای تودرتو است. بااینحال، این موضوع در «نوشتن» که میتواند سلسلهمراتب چیدمان عمیق را بهطور
کارآمد مدیریت کند، نگرانکننده نیست، بنابراین ConstraintLayout به این اندازه
مفید نیست.
با ConstraintLayout شروع کنید
برای استفاده از ConstraintLayout در «نوشتن»، باید این وابستگی را در
build.gradle (علاوهبر راهاندازی «نوشتن») اضافه کنید:
implementation "androidx.constraintlayout:constraintlayout-compose:$constraintlayout_compose_version"
ConstraintLayout در «نوشتن» به این روش بااستفاده از
DSL کار میکند:
- بااستفاده از
createRefs()یاcreateRefFor()، برای هر عنصر ترکیبشدنی درConstraintLayoutمرجع ایجاد کنید. - محدودیتها بااستفاده از تغییردهنده
constrainAs()ارائه میشوند که مرجع را بهعنوان پارامتر میگیرد و به شما امکان میدهد محدودیتهای آن را در لامبدای بدنه مشخص کنید. - محدودیتها بااستفاده از
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 را با حاشیه 16.dp به پایین Button محدود میکند.
Button و یک Text ترکیبی که در یک
ConstraintLayout به یکدیگر محدود شدهاند.
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 حاوی مفاهیمی مانند دستورالعملها، موانع، و زنجیرهها است که میتواند به قرار دادن عناصر در داخل عنصر ترکیبی شما کمک کند.
رهنمودها
خطوط راهنما کمکهای دیداری کوچکی برای طراحی چیدمانها هستند. عناصر ترکیبی را میتوان
به یک خط راهنما محدود کرد. دستورالعملها برای قرار دادن عناصر در یک
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: فضا قبلاز اولین و بعداز آخرین عنصر ترکیبی توزیع میشود، عناصر ترکیبی بدون فاصله بین یکدیگر کنار هم قرار میگیرند.