ב-Compose, רכיבים בממשק המשתמש מיוצגים על ידי הפונקציות הקומפוזביליות שפולטות חלק מממשק המשתמש כשהן מופעלות, ואז החלק הזה מתווסף לעץ של ממשק המשתמש שמוצג במסך. לכל רכיב בממשק המשתמש יש הורה אחד, ויכולים להיות לו הרבה צאצאים. כל רכיב נמצא גם בתוך רכיב ההורה שלו, שמוגדר כמיקום (x, y) וגודל, שמוגדר כ-width ו-height.
ההורים מגדירים את המגבלות של רכיבי הצאצאים שלהם. הרכיב מתבקש להגדיר את הגודל שלו בתוך המגבלות האלה. האילוצים מגבילים את הערכים המינימליים והמקסימליים של width ו-height של רכיב. אם לרכיב יש רכיבי צאצא, הוא יכול למדוד כל צאצא כדי לקבוע את הגודל שלו. אחרי שרכיב קובע את הגודל שלו ומדווח עליו, הוא יכול להגדיר איך למקם את רכיבי הצאצא שלו ביחס אליו, כפי שמתואר בפירוט במאמר יצירת פריסות בהתאמה אישית.
הפריסה של כל צומת בעץ ממשק המשתמש היא תהליך בן שלושה שלבים. כל צומת חייב:
- מודדים את הילדים
- הגודל ייקבע באופן אוטומטי
- מיקום הצאצאים שלו
השימוש בהיקפים מגדיר מתי אפשר למדוד ולהציב את הצאצאים.
אפשר למדוד פריסה רק במהלך שלבי המדידה והפריסה, ואפשר למקם רכיב צאצא רק במהלך שלבי הפריסה (ורק אחרי שהוא נמדד). בגלל היקפי ההרשאות של Compose, כמו MeasureScope ו-PlacementScope, זה נאכף בזמן הקימפול.
שימוש בשינוי הפריסה
אפשר להשתמש במשנה layout כדי לשנות את האופן שבו רכיב נמדד ומוצג. המשתנה מקבל למבדה. הפרמטרים שלו כוללים את הרכיב שאפשר למדוד, שמועבר בתור measurable, ואת האילוצים הנכנסים של הרכיב הניתן לTex, שמועברים בתור constraints. כך נראה שינוי של פריסה בהתאמה אישית:
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
הצגת Text במסך ושליטה במרחק מהחלק העליון לקו הבסיס של שורת הטקסט הראשונה. זה בדיוק מה שהמשתנה paddingFromBaseline עושה. אתם מטמיעים אותו כאן כדוגמה.
כדי לעשות את זה, משתמשים ב-modifier layout כדי למקם את הרכיב הניתן לTex במסך באופן ידני. כך נראית התוצאה כשהריפוד העליון של 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, מודדים אתTextשמיוצג על ידי הפרמטר שניתן למדידה באמצעות קריאה ל-measurable.measure(constraints). - כדי לציין את הגודל של התוכן הקומפוזבילי, צריך להפעיל את ה-method
layout(width, height), שמספקת גם פונקציית lambda שמשמשת למיקום הרכיבים שעטופים. במקרה הזה, הגובה הוא הגובה שלTextבתוספתplaceableY, שהואfirstBaselineToTopפחות קו הבסיס הראשון שלText. - כדי למקם את הרכיבים העטופים במסך, מפעילים את
placeable.placeRelative(x, y). אם לא ממקמים את הרכיבים העטופים, הם לא יוצגו. בפריסה מימין לשמאל,placeRelativeמשקף את המיקום שלx. אפשר לקרוא מידע נוסף בקטע כיוון הפריסה. המיקום שלyהואfirstBaselineToTopפחות קו הבסיס הראשון של הטקסט, כך שקו הבסיס הראשון נמצא במרחק שלfirstBaselineToTopמהחלק העליון.
כדי לוודא שהשינוי פועל כצפוי, משתמשים בשינוי הזה ב-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 משנה רק את ה-composable שקורא לו. כדי למדוד ולסדר כמה רכיבים קומפוזביליים, משתמשים ברכיב הקומפוזבילי 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 // ... } }
בדומה ל-modifier 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, והם ממוקמים על סמך ה-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 ב-CompositionLocal.
אם אתם ממקמים רכיבים קומפוזביליים באופן ידני במסך, ה-LayoutDirection זמין במאפיין layoutDirection של MeasureScope ב-modifier של layout או ברכיב הקומפוזבילי Layout.
כשמשתמשים ב-layoutDirection, ממקמים רכיבים קומפוזביליים באמצעות place. בניגוד ל-method placeRelative, הערך של place לא משתנה בהתאם לכיוון הפריסה (משמאל לימין לעומת מימין לשמאל).
פריסות בהתאמה אישית בפעולה
מידע נוסף על פריסות ומשתני שינוי זמין במאמר פריסות בסיסיות ב-Compose, ופריסות בהתאמה אישית בפעולה זמינות בדוגמאות של Compose שיוצרות פריסות בהתאמה אישית.
מידע נוסף
במקורות המידע הבאים אפשר למצוא מידע נוסף על פריסות בהתאמה אישית ב-Compose.
סרטונים
מומלץ בשבילכם
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- מדידות פנימיות בפריסות של Compose
- גרפיקה ב-Compose
- מגדירי Compose