ב-Compose, רכיבי ממשק המשתמש מיוצגים על ידי פונקציות שאפשר להוסיף להן פרמטרים, שיוצרות חלק מממשק המשתמש כשמפעילים אותן, ואז הן מתווספות לעץ של ממשק המשתמש שמוצג במסך. לכל רכיב בממשק המשתמש יש הורה אחד ויכולים להיות לו צאצאים רבים. כל רכיב ממוקם גם בתוך רכיב האב שלו, ומצוין כמיקום (x, y) וכגודל, שמצוין כ-width
ו-height
.
ההורים מגדירים את האילוצים של רכיבי הילדים. האלמנט מתבקש להגדיר את הגודל שלו במסגרת המגבלות האלה. מגבלות מגבילות את המינימום והמקסימום של width
ושל height
של רכיב. אם לרכיב יש רכיבי צאצא, יכול להיות שהוא ימדוד כל אחד מהצאצאים כדי לקבוע את הגודל שלו. אחרי שאלמנט קובע את הגודל שלו ומדווח עליו, הוא יכול להגדיר איך למקם את אלמנטי הצאצא שלו ביחס לעצמו, כמו שמתואר בפירוט במאמר בנושא יצירת פריסות בהתאמה אישית.
הפריסה של כל צומת בעץ ממשק המשתמש היא תהליך שכולל שלושה שלבים. כל צומת צריך:
- מדידת כל הפריטים המוסתרים של הרשומה
- הגודל נקבע באופן אוטומטי
- מיקום הילדים
השימוש בהיקפים מגדיר מתי אפשר למדוד את הילדים ולמקם אותם.
אפשר למדוד פריסה רק במהלך שלבי המדידה והפריסה, ואפשר למקם רכיב צאצא רק במהלך שלבי הפריסה (ורק אחרי שהוא נמדד). בגלל היקפי יצירה כמו MeasureScope
ו-PlacementScope
, האכיפה מתבצעת בזמן ההידור.
שימוש במקש לשינוי הפריסה
אפשר להשתמש במאפיין layout
כדי לשנות את האופן שבו מודדים ומסדרים רכיב. Layout
הוא ביטוי למדא; הפרמטרים שלו כוללים את הרכיב שאפשר למדוד, שמועבר כ-measurable
, ואת האילוצים הנכנסים של הרכיב הניתן להרכבה, שמועברים כ-constraints
. כך יכול להיראות משנה פריסה מותאם אישית:
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
הצגת Text
על המסך ושליטה במרחק מהחלק העליון של המסך עד לקו הבסיס של השורה הראשונה של הטקסט. זה בדיוק מה שעושה משנה התנהגות paddingFromBaseline
. כאן אנחנו מטמיעים אותו כדוגמה.
כדי לעשות את זה, משתמשים במחרוזת layout
כדי למקם את הרכיב הניתן להרכבה במסך באופן ידני. כך נראית ההתנהגות שמתקבלת כשמגדירים את Text
המרווח העליון כ-24.dp
:

paddingFromBaseline
.
הנה הקוד ליצירת הרווח הזה:
fun Modifier.firstBaselineToTop( firstBaselineToTop: Dp ) = layout { measurable, constraints -> // Measure the composable val placeable = measurable.measure(constraints) // Check the composable has a first baseline check(placeable[FirstBaseline] != AlignmentLine.Unspecified) val firstBaseline = placeable[FirstBaseline] // Height of the composable with padding - first baseline val placeableY = firstBaselineToTop.roundToPx() - firstBaseline val height = placeable.height + placeableY layout(placeable.width, height) { // Where the composable gets placed placeable.placeRelative(0, placeableY) } }
הסבר על הקוד:
- בפרמטר
measurable
של lambda, מודדים אתText
שמיוצג על ידי הפרמטר שניתן למדידה על ידי קריאה ל-measurable.measure(constraints)
. - כדי לציין את הגודל של הקומפוזבילי, קוראים לשיטה
layout(width, height)
שמספקת גם למבדה שמשמשת למיקום האלמנטים העטופים. במקרה הזה, זה הגובה בין קו הבסיס האחרון לבין המרווח הפנימי העליון שנוסף. - כדי למקם את הרכיבים העטופים במסך, קוראים ל-
placeable.place(x, y)
. אם לא ממקמים את הרכיבים העוטפים, הם לא יוצגו. המיקוםy
מתאים לריווח העליון: המיקום של קו הבסיס הראשון של הטקסט.
כדי לוודא שהפעולה מתבצעת כצפוי, משתמשים במקש הצירוף הזה ב-Text
:
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }

Text
שניתן להרכבה ולתצוגה מקדימה.
יצירת פריסות בהתאמה אישית
המשנה layout
משנה רק את הקומפוזיציה של השיחה. כדי למדוד ולסדר כמה רכיבים שאפשר להרכיב, משתמשים במקום זאת ברכיב שאפשר להרכיב Layout
. קומפוננטה שאפשר להרכיב ממנה קומפוננטות אחרות, שמאפשרת למדוד ולסדר את הרכיבים הצאצאים באופן ידני. כל הפריסות ברמה גבוהה יותר, כמו Column
ו-Row
, מבוססות על Layout
.
בדוגמה הזו אנחנו יוצרים גרסה בסיסית מאוד של Column
. רוב הפריסות בהתאמה אישית בנויות לפי התבנית הבאה:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
בדומה לשינוי layout
, measurables
היא רשימת הילדים שצריך למדוד ו-constraints
הן המגבלות מההורה.
בהתאם לאותה לוגיקה כמו קודם, אפשר להטמיע את MyBasicColumn
כך:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
הקומפוזיציות של הצאצא מוגבלות על ידי האילוצים Layout
(בלי האילוצים minHeight
), והן ממוקמות על סמך yPosition
של הקומפוזיציה הקודמת.
כך משתמשים ברכיב הניתן להרכבה בהתאמה אישית:
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }

Column
בהתאמה אישית.
כיוון הפריסה
כדי לשנות את כיוון הפריסה של רכיב שאפשר להרכיב, משנים את ההרכב המקומי של LocalLayoutDirection
.
אם מציבים את התוכן הקומפוזבילי במסך באופן ידני, LayoutDirection
הוא חלק מ-LayoutScope
של משנה layout
או של תוכן קומפוזבילי Layout
.
כשמשתמשים ב-layoutDirection
, ממקמים את רכיבי ה-Composable באמצעות place
. בניגוד לשיטה
placeRelative
, place
לא משתנה בהתאם לכיוון הפריסה (משמאל לימין או מימין לשמאל).
פריסות בהתאמה אישית בפעולה
מידע נוסף על פריסות ועל שינויים אפשר לקרוא במאמר פריסות בסיסיות בכתיבה. דוגמאות לפריסות בהתאמה אישית אפשר לראות במאמר דוגמאות לכתיבה שיוצרות פריסות בהתאמה אישית.
מידע נוסף
מידע נוסף על פריסות בהתאמה אישית בכלי הכתיבה זמין במקורות המידע הבאים.
סרטונים
מומלץ
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- מדידות פנימיות בפריסות של Compose
- גרפיקה ב-Compose
- הרכבת מגבילים