Mit dem Layoutmodell „Schreiben“ können Sie mit AlignmentLine
benutzerdefinierte
Ausrichtungslinien, die von übergeordneten Layouts verwendet werden können, um ihre
Kinder. Beispiel:
Row
können die benutzerdefinierten Ausrichtungslinien der untergeordneten Elemente verwenden, um sie auszurichten.
Wenn ein Layout einen Wert für eine bestimmte AlignmentLine
bereitstellt,
Eltern können diesen Wert nach der Messung über die Placeable.get
abrufen.
im entsprechenden
Placeable
-Instanz.
Basierend auf der Position von AlignmentLine
können die übergeordneten Elemente
und legt dann die Positionierung der untergeordneten Elemente fest.
Einige zusammensetzbare Funktionen in „Schreiben“ sind bereits mit Ausrichtungslinien ausgestattet. Beispiel: Der Parameter
BasicText
zusammensetzbare Funktion macht die Ausrichtungslinien FirstBaseline
und LastBaseline
sichtbar.
Im Beispiel unten hat ein benutzerdefiniertes LayoutModifier
mit dem Namen
firstBaselineToTop
liest die FirstBaseline
, um der Text
einen Abstand hinzuzufügen
beginnend bei der ersten Baseline.
Abbildung 1: Zeigt den Unterschied zwischen dem Hinzufügen eines normalen Abstands zu einem Element, und das Auffüllen der Referenz eines Textelements.
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)) } }
Um die FirstBaseline
in diesem Beispiel zu lesen,
placeable [FirstBaseline]
wird in der Messphase verwendet.
Benutzerdefinierte Ausrichtungslinien erstellen
Beim Erstellen eines benutzerdefinierten Layout
zusammensetzbaren oder benutzerdefinierten LayoutModifier
verwenden, können Sie
benutzerdefinierte Ausrichtungslinien, damit sie von anderen
übergeordneten zusammensetzbaren Funktionen verwendet werden können,
und ihre Kinder entsprechend zu positionieren.
Das folgende Beispiel zeigt eine benutzerdefinierte zusammensetzbare Funktion BarChart
, die zwei zusammensetzbare Funktionen
Ausrichtungslinien, MaxChartValue
und MinChartValue
, sodass andere zusammensetzbare Funktionen
am Höchst- und Mindestdatenwert des Diagramms ausgerichtet werden. Zwei Text
Max und Min, wurden an der Mitte des benutzerdefinierten
Ausrichtungslinien.
Abbildung 2: BarChart
zusammensetzbar, wobei der Text am Maximalwert und
Minimaler Datenwert.
Benutzerdefinierte Ausrichtungslinien werden als Variablen der obersten Ebene in Ihrem Projekt definiert.
/** * 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) })
Die benutzerdefinierten Ausrichtungslinien, um unser Beispiel zu erstellen, sind vom Typ
HorizontalAlignmentLine
, wie
werden die untergeordneten Elemente vertikal ausgerichtet. Eine Zusammenführungsrichtlinie wird übergeben als
-Parameter, falls mehrere Layouts einen Wert für diese Ausrichtungslinien bereitstellen. Als
die Koordinaten des Layoutsystems „Compose“ und die Canvas
Koordinaten stellen [0, 0]
dar, die obere linke Ecke sowie die Achse x
und y
sind
positiv nach unten, sodass der Wert MaxChartValue
immer kleiner ist als
MinChartValue
Daher lautet die Fusionsrichtlinie für das höchste Diagramm „min
“.
Datenwert-Baseline und max
für die minimale Referenz der Diagrammdatenwerte.
Geben Sie beim Erstellen eines benutzerdefinierten Layout
- oder LayoutModifier
-Elements eine benutzerdefinierte Ausrichtung an.
Zeilen in der MeasureScope.layout
mit einem alignmentLines: Map<AlignmentLine, Int>
-Wert
.
@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() ) ) {} } } } } }
Direkte und indirekte übergeordnete Elemente dieser zusammensetzbaren Funktion können die Ausrichtung verarbeiten.
Linien. Die folgende zusammensetzbare Funktion erstellt ein benutzerdefiniertes Layout, das als
Parameter zwei Text
-Flächen und Datenpunkte und richtet die beiden Texte an den
maximale und minimale Diagrammdatenwerte. Die Vorschau dieser zusammensetzbaren Funktion ist
was in Abbildung 2 dargestellt ist.
@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) ) } }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Grafiken in „Compose“
- Benutzerdefinierte Layouts {:#custom-layouts }
- Intrinsische Messungen in „Layouts erstellen“