ConstraintLayout
הוא פריסה שמאפשרת למקם רכיבי Composable ביחס לרכיבי Composable אחרים במסך. הוא מהווה חלופה לשימוש בכמה רכיבים מוטמעים של Row
, Column
, Box
ופריסות מותאמות אישית אחרות. ConstraintLayout
is useful when implementing larger layouts with more complicated alignment
requirements.
כדאי להשתמש ב-ConstraintLayout
בתרחישים הבאים:
- כדי להימנע מהוספה של כמה תגי
Column
ו-Row
למיקום רכיבים במסך, וכך לשפר את קריאות הקוד. - כדי למקם רכיבי Composable ביחס לרכיבי Composable אחרים, או כדי למקם רכיבי Composable על סמך הנחיות, מחסומים או שרשראות.
במערכת View, ConstraintLayout
הייתה הדרך המומלצת ליצור פריסות גדולות ומורכבות, כי היררכיית תצוגה שטוחה הייתה טובה יותר לביצועים מאשר תצוגות מקוננות. עם זאת, אין בעיה כזו ב-Compose, כי הוא יכול לטפל ביעילות בהיררכיות עמוקות של פריסות.
רוצה להתחיל לצפות בתכנים של ConstraintLayout
?
כדי להשתמש ב-ConstraintLayout
בכתיבת אימייל, צריך להוסיף את התלות הזו ל-build.gradle
(בנוסף להגדרת הכתיבה):
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
.
Decoupled API
בדוגמה ConstraintLayout
, האילוצים מוגדרים בשורה, עם משנה בקומפוזיציה שהם חלים עליה. עם זאת, יש מצבים שבהם עדיף להפריד את האילוצים מהפריסות שהם חלים עליהן. לדוגמה, יכול להיות שתרצו לשנות את האילוצים בהתאם להגדרת המסך, או ליצור אנימציה בין שני סטים של אילוצים.
במקרים כאלה, אפשר להשתמש ב-ConstraintLayout
בדרך אחרת:
- מעבירים את
ConstraintSet
כפרמטר אלConstraintLayout
. - משתמשים במאפיין
layoutId
כדי להקצות הפניות שנוצרו ב-ConstraintSet
לרכיבים שאפשר להרכיב.
@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
מכיל מושגים כמו הנחיות, מחסומים ושרשראות שיכולים לעזור במיקום אלמנטים בתוך ה-Composable.
הנחיות
ההנחיות הן עזרים חזותיים קטנים לעיצוב פריסות. אפשר להגביל את השימוש ברכיבים הניתנים להרכבה להנחיה מסוימת. הנחיות שימושיות למיקום רכיבים בdp
או בpercentage
מסוימים בתוך פונקציית ה-Composable של ההורה.
יש שני סוגים שונים של קווי הנחיה: אנכיים ואופקיים. שתי התמונות לרוחב הן 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()
.
מחסומים
Barriers מפנה לכמה רכיבים שניתנים להרכבה כדי ליצור קו הנחיה וירטואלי שמבוסס על הווידג'ט הקיצוני ביותר בצד שצוין.
כדי ליצור מחסום, משתמשים בתו 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
: הרווח מחולק באופן שווה בין כל רכיבי ה-Composable, בלי רווח פנוי לפני רכיב ה-Composable הראשון או אחרי רכיב ה-Composable האחרון. -
ChainStyle.Packed
: הרווח מחולק לפני הרכיב הראשון ואחרי הרכיב האחרון. הרכיבים מוצמדים זה לזה בלי רווחים ביניהם.
מידע נוסף
במאמר הזה מוסבר איך להשתמש ב-ConstraintLayout
בכתיבת אימייל, עם דוגמאות לשימוש בממשקי ה-API.ConstraintLayout
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- התמקדות בכתיבה
- Kotlin ל-Jetpack פיתוח נייטיב
- העקרונות הבסיסיים של פריסת המסך בכתיבת אימייל