Compose 版面配置模型可讓您使用 AlignmentLine
建立自訂
上層布係版面配置可使用此對齊線對齊和定位
。例如:
Row
敬上
可以使用子項的自訂對齊線來對齊。
如果版面配置提供特定 AlignmentLine
的值,該版面配置的
家長可以使用 Placeable.get
,在測量後讀取此值
相同的運算子
Placeable
執行個體。
根據 AlignmentLine
的位置,家長可以
然後決定子項的位置
Compose 中的部分可組合項已帶有對齊線。舉例來說,
BasicText
敬上
可組合函式會顯示 FirstBaseline
和 LastBaseline
對齊線。
在以下範例中,名為「LayoutModifier
」的自訂 LayoutModifier
firstBaselineToTop
會讀取 FirstBaseline
,將邊框間距新增至 Text
從第一個基準開始
圖 1. 顯示將標準邊框間距新增至元素的差異 並將邊框間距套用至文字元素的基準。
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
可組合函式的文字符合最大值和
資料值。
自訂對齊線行在專案中定義為頂層變數。
/** * 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
,
這些元件是用來垂直對齊子項系統會以
參數,藉此為這些對齊線提供一個值。阿斯
Compose 版面配置系統座標和 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() ) ) {} } } } } }
這個可組合函式的直接和間接父項可以使用對齊方式
線條。下列可組合函式可建立自訂版面配置,將
參數 2 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 版面配置中的內建函式測量資料