ConstraintLayout
הוא פריסה שמאפשרת למקם רכיבים של Composable ביחס לרכיבים אחרים של Composable במסך. זוהי אלטרנטיבה לשימוש במספר רכיבים בתצוגת עץ של Row
, Column
, Box
ורכיבי פריסה מותאמים אישית אחרים. ConstraintLayout
שימושי כשמטמיעים פריסות גדולות יותר עם דרישות התאמה מורכבות יותר.
כדאי להשתמש ב-ConstraintLayout
בתרחישים הבאים:
- כדי להימנע מהטמעה של כמה רכיבי
Column
ו-Row
למיקום רכיבים במסך, וכדי לשפר את קריאת הקוד. - כדי למקם רכיבים מורכבים ביחס לרכיבים מורכבים אחרים, או כדי למקם רכיבים מורכבים על סמך קווים מנחים, חסמים או שרשראות.
במערכת התצוגה, ConstraintLayout
הייתה הדרך המומלצת ליצור פריסות גדולות ומורכבות, כי היררכיית תצוגה רגילה משפרת את הביצועים יותר מתצוגות בתצוגות. עם זאת, זה לא בעיה ב-Compose, שיכול לטפל ביעילות בהיררכיות עיצוב עמוקות.
התחל לעבוד עם ConstraintLayout
כדי להשתמש ב-ConstraintLayout
ב-Compose, צריך להוסיף את התלות הזו ב-build.gradle
(בנוסף להגדרת Compose):
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
ConstraintLayout
ב-Compose פועל באופן הבא באמצעות DSL:
- יוצרים הפניות לכל רכיב ב-
ConstraintLayout
באמצעותcreateRefs()
אוcreateRefFor()
- האילוצים מוצגים באמצעות המשתנה המשנה
constrainAs()
, שמקבל את ההפניה כפרמטר ומאפשר לציין את האילוצים שלו ב-body של הלמה. - האילוצים מצוינים באמצעות
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
.
API מנותק
בדוגמה ConstraintLayout
, האילוצים מוגדרים בשורה, עם שינוי ברכיב ה-Composable שאליו הם חלים. עם זאת, יש מצבים שבהם עדיף לנתק את האילוצים מהפריסות שהם חלים עליהן. לדוגמה, יכול להיות שתרצו לשנות את האילוצים על סמך הגדרת המסך, או ליצור אנימציה בין שתי קבוצות של אילוצים.
במקרים כאלה, אפשר להשתמש ב-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
מכיל מושגים כמו הנחיות, מחסומים שרשראות שיכולים לעזור למקם אלמנטים בתוך ה-Composable.
הנחיות
ההנחיות הן עזרים חזותיים קטנים שיעזרו לכם לעצב פריסות. אפשר להגביל את הרכיבים הניתנים לשילוב להנחיה. ההנחיות מועילות למיקום רכיבים ב-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
: הרווח מופיע לפני ה-Composable הראשון ואחרי ה-Composable האחרון, וה-Composables מקובצים יחד ללא רווחים ביניהם.
מידע נוסף
מידע נוסף על ConstraintLayout
ב-Compose זמין בממשקי ה-API בפעולה, בדוגמאות ל-Compose שמשתמשות ב-ConstraintLayout
.
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- התמקדות בכתיבה
- Kotlin ל-Jetpack פיתוח נייטיב
- יסודות של יצירת פריסה