Compose düzen modeli, üst yerleşimlerin alt öğelerini hizalamak ve konumlandırmak için kullanabileceği özel hizalama çizgileri oluşturmak üzere AlignmentLine kullanmanıza olanak tanır. Örneğin, Row, alt öğelerini hizalamak için alt öğelerinin özel hizalama çizgilerini kullanabilir.
Bir düzen belirli bir AlignmentLine için değer sağladığında, düzenin üst öğeleri ölçümden sonra ilgili Placeable örneğinde Placeable.get operatörünü kullanarak bu değeri okuyabilir. Ebeveynler, AlignmentLine öğesinin konumuna göre alt öğelerin konumuna karar verebilir.
Compose'daki bazı composable'lar hizalama çizgileriyle birlikte gelir. Örneğin, BasicText composable, FirstBaseline ve LastBaseline hizalama çizgilerini gösterir.
Aşağıdaki örnekte, firstBaselineToTop adlı özel bir LayoutModifier, ilk taban çizgisinden başlayarak Text öğesine dolgu eklemek için FirstBaseline değerini okur.
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)) } }
Örnekteki FirstBaseline değerini okumak için ölçüm aşamasında placeable [FirstBaseline] kullanılır.
Özel hizalama çizgileri oluşturma
Özel bir Layout composable veya özel bir LayoutModifier oluştururken özel hizalama çizgileri sağlayabilirsiniz. Böylece diğer üst composable'lar, alt öğelerini buna göre hizalamak ve konumlandırmak için bu çizgileri kullanabilir.
Aşağıdaki örnekte, diğer composable'ların grafiğin maksimum ve minimum veri değerine hizalanabilmesi için iki hizalama çizgisi (MaxChartValue ve MinChartValue) gösteren özel bir BarChart composable gösterilmektedir. Maks. ve Min. adlı iki metin öğesi, özel hizalama çizgilerinin ortasına hizalanmış.
BarChart composable'ı ile maksimum ve minimum veri değerine hizalanmış metin.Özel hizalama çizgileri, projenizde üst düzey değişkenler olarak tanımlanır.
/** * 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) })
Örneğimizi oluşturmak için kullanılan özel hizalama çizgileri, alt öğeleri dikey olarak hizalamak için kullanıldığından HorizontalAlignmentLine türündedir. Birden fazla düzen bu hizalama çizgileri için bir değer sağlıyorsa birleştirme politikası parametre olarak iletilir. Oluşturma düzeni sistemi koordinatları ve Canvas koordinatları [0, 0], sol üst köşe ve x ile y ekseni aşağı doğru pozitif olduğundan MaxChartValue değeri her zaman MinChartValue değerinden küçük olur. Bu nedenle, birleştirme politikası maksimum grafik veri değeri referansı için min, minimum grafik veri değeri referansı için max olur.
Özel bir Layout veya LayoutModifier oluştururken alignmentLines: Map<AlignmentLine, Int> parametresi alan MeasureScope.layout yönteminde özel hizalama çizgileri belirtin.
@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() ) ) {} } } } } }
Bu composable'ın doğrudan ve dolaylı üst öğeleri, hizalama çizgilerini kullanabilir. Aşağıdaki composable, parametre olarak iki Text yuvası ve veri noktası alan özel bir düzen oluşturur ve iki metni maksimum ve minimum grafik veri değerlerine hizalar. Bu composable'ın önizlemesi,
Şekil 2'de gösterilmektedir.
@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) ) } }
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- Compose'da grafikler
- Özel düzenler {:#custom-layouts }
- Compose düzenlerinde içsel ölçümler