Im 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
angibt, können die übergeordneten Elemente des Layouts diesen Wert nach der Messung mit dem Operator Placeable.get
auf der entsprechenden Placeable
-Instanz lesen.
Anhand der Position der AlignmentLine
können die Eltern dann die Position der Kinder festlegen.
Einige Compose-Elemente haben bereits Ausrichtungslinien. 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 Innenrands zu einem Element, und auf die Referenz eines Textelements auffüllen.
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 das FirstBaseline
in diesem Beispiel zu lesen,
placeable [FirstBaseline]
wird in der Messphase verwendet.
Benutzerdefinierte Ausrichtungslinien erstellen
Wenn Sie ein benutzerdefiniertes Layout
- oder LayoutModifier
-Element erstellen, können Sie benutzerdefinierte Ausrichtungslinien angeben, mit denen andere übergeordnete Elemente ihre untergeordneten Elemente entsprechend ausrichten und positionieren können.
Das folgende Beispiel zeigt ein benutzerdefiniertes BarChart
-Kompositelement mit zwei Ausrichtungslinien, MaxChartValue
und MinChartValue
, damit andere Kompositionen an den Höchst- und Mindestdatenwert des Diagramms ausgerichtet werden können. Zwei Text
Max und Min, wurden an der Mitte des benutzerdefinierten
Ausrichtungslinien.
Abbildung 2: BarChart
zusammensetzbar mit Text am Maximal und
Minimaler Datenwert.
Benutzerdefinierte Ausrichtungslinien werden in Ihrem Projekt als Variablen der obersten Ebene 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 als Parameter übergeben, falls mehrere Layouts einen Wert für diese Ausrichtungslinien angeben. Da die Koordinaten des Compose-Layoutsystems und die Canvas
-Koordinaten [0, 0]
darstellen, sind die linke obere Ecke und die x
- und y
-Achsen nach unten positiv. Der Wert für MaxChartValue
ist also immer kleiner als MinChartValue
. Daher ist die Zusammenführungsrichtlinie min
für den Höchstwert der Diagrammdaten und max
für den Mindestwert der Diagrammdaten.
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 oder indirekte übergeordnete dieser zusammensetzbaren Funktion kann 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) ) } }
Derzeit liegen keine Empfehlungen vor.
Versuchen Sie, sich bei Ihrem Google-Konto anzumelden.