Eine der Regeln von „Compose“ besagt, dass Sie Ihre untergeordneten Elemente nur einmal erfassen sollten. bei zweimaligen Messungen einer Laufzeitausnahme. Es gibt jedoch Zeiten, wenn Sie Informationen über Ihre Kinder benötigen, bevor Sie sie messen.
Mit Intrinsics können Sie untergeordnete Elemente abfragen, bevor sie tatsächlich gemessen werden.
Bei einer zusammensetzbaren Funktion können Sie nach intrinsicWidth
oder intrinsicHeight
fragen:
(min|max)IntrinsicWidth
: Was ist aufgrund dieser Breite der minimale/maximale mit der Sie Ihre Inhalte richtig darstellen können?(min|max)IntrinsicHeight
: Was ist aufgrund dieser Höhe der minimale/maximale Wert wie groß Sie Ihre Inhalte richtig darstellen können?
Wenn Sie beispielsweise die minIntrinsicHeight
einer Text
mit unendlicher
height
wird das height
von Text
zurückgegeben, als ob der Text in einem
in einer Zeile.
Intrinsik in Aktion
Stellen Sie sich vor, wir möchten eine zusammensetzbare Funktion erstellen, die zwei Texte auf der Bildschirm durch eine Trennlinie getrennt:
Wie können wir das tun? Wir können ein Row
mit zwei Text
-Elementen haben, das wie folgt erweitert wird:
und ein Divider
in der Mitte. Divider
soll so aussehen:
hoch als die höchste Text
und dünn (width = 1.dp
).
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) Divider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
In der Vorschau sehen wir, dass Divider
den gesamten Bildschirm einnimmt und
wollen wir das nicht:
Das liegt daran, dass Row
jedes Kind einzeln misst und die Größe
Text
kann nicht zur Einschränkung von Divider
verwendet werden. Wir möchten, dass die Divider
den verfügbaren Platz mit einer bestimmten Höhe. Dafür können wir den
height(IntrinsicSize.Min)
-Modifikator
height(IntrinsicSize.Min)
legt fest, dass seine untergeordneten Elemente so groß sind wie
ihre minimale intrinsische Höhe haben. Da sie rekursiv ist, fragt sie Row
ab
Kinder minIntrinsicHeight
.
Wenn wir dies auf unseren Code anwenden, funktioniert es wie erwartet:
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier.height(IntrinsicSize.Min)) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) Divider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } } // @Preview @Composable fun TwoTextsPreview() { MaterialTheme { Surface { TwoTexts(text1 = "Hi", text2 = "there") } } }
Mit Vorschau:
Die minIntrinsicHeight
der zusammensetzbaren Funktion „Row
“ ist das Maximum
minIntrinsicHeight
seiner untergeordneten Elemente. Der Wert des Divider
-Elements
minIntrinsicHeight
ist 0, da es keinen Platz belegt, wenn keine Einschränkungen vorhanden sind
gegeben; der Text
minIntrinsicHeight
ist der des Textes für eine bestimmte
width
. Daher ist die height
-Beschränkung des Row
-Elements die maximale
minIntrinsicHeight
von Text
. Divider
erweitert seine height
dann um
Die durch Row
vorgegebene Einschränkung height
.
Intrinsische Elemente in Ihren benutzerdefinierten Layouts
Wenn Sie einen benutzerdefinierten Layout
- oder layout
-Modifikator erstellen, sind intrinsische Messwerte
werden anhand von Schätzungen automatisch berechnet. Daher entspricht der Parameter
Berechnungen möglicherweise nicht für alle Layouts korrekt sind. Diese APIs bieten Optionen
um diese Standardeinstellungen zu überschreiben.
So legst du die intrinsischen Messwerte deiner benutzerdefinierten Layout
fest:
minIntrinsicWidth
, minIntrinsicHeight
, maxIntrinsicWidth
und maxIntrinsicHeight
der
MeasurePolicy
Schnittstelle beim Erstellen.
@Composable fun MyCustomComposable( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( content = content, modifier = modifier, measurePolicy = object : MeasurePolicy { override fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurables: List<IntrinsicMeasurable>, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. } ) }
Beim Erstellen des benutzerdefinierten layout
-Modifikator die zugehörigen Methoden überschreiben
in der LayoutModifier
-Oberfläche.
fun Modifier.myCustomModifier(/* ... */) = this then object : LayoutModifier { override fun MeasureScope.measure( measurable: Measurable, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurable: IntrinsicMeasurable, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Benutzerdefinierte Layouts {:#custom-layouts }
- Ausrichtungslinien in Jetpack Compose
- Jetpack-Compose-Phasen