מודל הפריסה Compose מאפשר לכם להשתמש ב- AlignmentLine
כדי ליצור קווי יישור מותאמים אישית, שפריסות ראשיות יכולות להשתמש בהם כדי ליישר ולמקם את רכיבי הצאצא שלהן. לדוגמה,
Row
יכול להשתמש בקווי היישור המותאמים אישית של הילדים כדי ליישר אותם.
כשפריסת רכיבים מספקת ערך לAlignmentLine
מסוים, רכיבי האב של הפריסה יכולים לקרוא את הערך הזה אחרי המדידה, באמצעות האופרטור Placeable.get
במופע Placeable
המתאים.
על סמך המיקום של AlignmentLine
, ההורים יכולים להחליט על המיקום של הילדים.
חלק מהקומפוזיציות ב-Compose כבר מגיעות עם קווי יישור. לדוגמה, הרכיב BasicText
מאפשר להציג את קווי היישור FirstBaseline
ו-LastBaseline
.
בדוגמה שלמטה, LayoutModifier
מותאם אישית שנקרא firstBaselineToTop
קורא את FirstBaseline
כדי להוסיף ריווח פנימי ל-Text
החל מקו הבסיס הראשון שלו.
איור 1. מראה את ההבדל בין הוספת ריווח רגיל לרכיב לבין החלת ריווח על קו הבסיס של רכיב Text.
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) } } @Preview @Composable private fun TextWithPaddingToBaseline() { MaterialTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } }
כדי לקרוא את FirstBaseline
בדוגמה, נעשה שימוש ב-placeable [FirstBaseline]
בשלב המדידה.
יצירת קווי יישור מותאמים אישית
כשיוצרים קומפוזיציה מותאמת אישית Layout
או LayoutModifier
מותאם אישית, אפשר לספק קווי יישור מותאמים אישית כדי שקומפוזיציות אחרות ברמת ההורה יוכלו להשתמש בהם ליישור ולמיקום של רכיבי הצאצא שלהן בהתאם.
בדוגמה הבאה מוצג קומפוזיבל מותאם אישית BarChart
שחושף שני קווי יישור, MaxChartValue
ו-MinChartValue
, כדי שקומפוזיבלים אחרים יוכלו להתיישר לפי ערך הנתונים המקסימלי והמינימלי של התרשים. שני רכיבי טקסט, Max ו-Min, מיושרים למרכז של קווי היישור המותאמים אישית.
איור 2. BarChart
composable with Text aligned to the maximum and
minimum data value.
קווי יישור מותאמים אישית מוגדרים כמשתנים ברמה העליונה בפרויקט.
/** * AlignmentLine defined by the maximum data value in a [BarChart] */ private val MaxChartValue = HorizontalAlignmentLine(merger = { old, new -> min(old, new) }) /** * AlignmentLine defined by the minimum data value in a [BarChart] */ private val MinChartValue = HorizontalAlignmentLine(merger = { old, new -> max(old, new) })
קווי היישור המותאמים אישית שמשמשים ליצירת הדוגמה הם מסוג
HorizontalAlignmentLine
, כי הם משמשים ליישור אנכי של רכיבי צאצא. אם כמה פריסות מספקות ערך לקווי היישור האלה, מדיניות המיזוג מועברת כפרמטר. מכיוון שמערכת הפריסה של כלי הכתיבה מתאמת את הקואורדינטות וקואורדינטות Canvas
מייצגות את [0, 0]
, הפינה הימנית העליונה והצירים x
ו-y
חיוביים כלפי מטה, הערך של MaxChartValue
תמיד יהיה קטן מ-MinChartValue
. לכן, מדיניות המיזוג היא min
עבור בסיס הערך המקסימלי של נתוני התרשים, ו-max
עבור בסיס הערך המינימלי של נתוני התרשים.
כשיוצרים Layout
או LayoutModifier
מותאמים אישית, מציינים קווי יישור מותאמים אישית בשיטה MeasureScope.layout
, שמקבלת פרמטר alignmentLines: Map<AlignmentLine, Int>
.
@Composable private fun BarChart( dataPoints: List<Int>, modifier: Modifier = Modifier, ) { val maxValue: Float = remember(dataPoints) { dataPoints.maxOrNull()!! * 1.2f } BoxWithConstraints(modifier = modifier) { val density = LocalDensity.current with(density) { // ... // Calculate baselines val maxYBaseline = // ... val minYBaseline = // ... Layout( content = {}, modifier = Modifier.drawBehind { // ... } ) { _, constraints -> with(constraints) { layout( width = if (hasBoundedWidth) maxWidth else minWidth, height = if (hasBoundedHeight) maxHeight else minHeight, // Custom AlignmentLines are set here. These are propagated // to direct and indirect parent composables. alignmentLines = mapOf( MinChartValue to minYBaseline.roundToInt(), MaxChartValue to maxYBaseline.roundToInt() ) ) {} } } } } }
ההורים הישירים והעקיפים של הרכיב הזה יכולים להשתמש בקווי היישור. הקומפוזיציה הבאה יוצרת פריסה בהתאמה אישית שמקבלת כפרמטר שני Text
מקטעים ונקודות נתונים, ומיישרת את שני הטקסטים לערכי הנתונים המקסימליים והמינימליים בתרשים. התצוגה המקדימה של הרכיב הזה היא מה שמוצג באיור 2.
@Composable private fun BarChartMinMax( dataPoints: List<Int>, maxText: @Composable () -> Unit, minText: @Composable () -> Unit, modifier: Modifier = Modifier, ) { Layout( content = { maxText() minText() // Set a fixed size to make the example easier to follow BarChart(dataPoints, Modifier.size(200.dp)) }, modifier = modifier ) { measurables, constraints -> check(measurables.size == 3) val placeables = measurables.map { it.measure(constraints.copy(minWidth = 0, minHeight = 0)) } val maxTextPlaceable = placeables[0] val minTextPlaceable = placeables[1] val barChartPlaceable = placeables[2] // Obtain the alignment lines from BarChart to position the Text val minValueBaseline = barChartPlaceable[MinChartValue] val maxValueBaseline = barChartPlaceable[MaxChartValue] layout(constraints.maxWidth, constraints.maxHeight) { maxTextPlaceable.placeRelative( x = 0, y = maxValueBaseline - (maxTextPlaceable.height / 2) ) minTextPlaceable.placeRelative( x = 0, y = minValueBaseline - (minTextPlaceable.height / 2) ) barChartPlaceable.placeRelative( x = max(maxTextPlaceable.width, minTextPlaceable.width) + 20, y = 0 ) } } } @Preview @Composable private fun ChartDataPreview() { MaterialTheme { BarChartMinMax( dataPoints = listOf(4, 24, 15), maxText = { Text("Max") }, minText = { Text("Min") }, modifier = Modifier.padding(24.dp) ) } }
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- גרפיקה ב-Compose
- פריסות בהתאמה אישית {:#custom-layouts }
- מדידות פנימיות בפריסות של Compose