Model tata letak Compose memungkinkan Anda menggunakan AlignmentLine
untuk membuat garis perataan
kustom yang dapat digunakan oleh tata letak induk untuk meratakan dan memosisikan
turunannya. Misalnya,
Row
dapat menggunakan garis perataan kustom turunannya untuk meratakannya.
Saat tata letak memberikan nilai untuk AlignmentLine
tertentu, induk
tata letak dapat membaca nilai ini setelah melakukan pengukuran, menggunakan operator Placeable.get
pada instance Placeable
yang terkait.
Berdasarkan posisi AlignmentLine
, induk kemudian dapat
memutuskan posisi turunan.
Beberapa composable di Compose sudah dilengkapi dengan garis perataan. Misalnya, composable
BasicText
menampilkan garis perataan FirstBaseline
dan LastBaseline
.
Pada contoh di bawah, LayoutModifier
kustom yang disebut
firstBaselineToTop
membaca FirstBaseline
untuk menambahkan padding ke Text
mulai dari dasar pengukuran pertamanya.
Gambar 1. Menampilkan perbedaan antara menambahkan padding normal ke elemen, dan menerapkan padding ke dasar pengukuran elemen Teks.
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)) } }
Untuk membaca FirstBaseline
dalam contoh ini,
placeable [FirstBaseline]
digunakan dalam fase pengukuran.
Membuat garis perataan kustom
Saat membuat composable Layout
kustom atau LayoutModifier
kustom, Anda dapat memberikan
garis perataan khusus sehingga composable induk lain dapat menggunakannya untuk meratakan dan
memosisikan turunannya sebagaimana mestinya.
Contoh berikut menunjukkan composable BarChart
kustom yang mengekspos dua
garis perataan, MaxChartValue
, dan MinChartValue
, sehingga composable lain
dapat diratakan dengan nilai data minimum dan minimum pada diagram. Dua elemen
teks, Maks dan Min, telah diratakan ke tengah
garis perataan khusus.
Gambar 2. Composable BarChart
dengan Teks yang diratakan dengan nilai data
maksimum dan minimum.
Garis perataan khusus ditetapkan sebagai variabel level atas dalam project Anda.
/** * 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) })
Garis perataan khusus untuk membuat contoh adalah jenis
HorizontalAlignmentLine
, karena
digunakan untuk meratakan turunan secara vertikal. Kebijakan penggabungan diteruskan sebagai
parameter jika beberapa tata letak memberikan nilai untuk garis perataan ini. Karena
koordinat sistem tata letak Compose dan koordinat Canvas
mewakili [0, 0]
, pojok kiri atas dan sumbu x
dan y
positif ke bawah, sehingga nilai MaxChartValue
akan selalu lebih kecil dari
MinChartValue
. Oleh karena itu, kebijakan penggabungannya adalah min
untuk dasar pengukuran
nilai data diagram maksimum, dan max
untuk dasar pengukuran nilai data diagram minimum.
Saat membuat Layout
atau LayoutModifier
kustom, tentukan garis perataan
khusus dalam metode MeasureScope.layout
,
yang menggunakan parameter
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() ) ) {} } } } } }
Induk langsung dan tidak langsung dari composable ini dapat menggunakan garis
perataan. Composable berikut akan membuat tata letak kustom yang menggunakan
parameter, dua slot Text
dan titik data, serta meratakan dua teks tersebut ke
nilai data diagram maksimum dan minimum. Pratinjau composable ini adalah
yang ditampilkan pada Gambar 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) ) } }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Grafis di Compose
- Tata letak kustom {:#custom-layouts }
- Pengukuran intrinsik di tata letak Compose