Mit Modifikatoren können Sie ein Composable-Element dekorieren oder erweitern. Mit Modifikatoren können Sie beispielsweise Folgendes tun:
- Größe, Layout, Verhalten und Darstellung der Composable-Funktion ändern
- Informationen wie Labels für Barrierefreiheit hinzufügen
- Nutzereingabe verarbeiten
- Allgemeine Interaktionen hinzufügen, z. B. ein Element anklickbar, scrollbar, ziehbar oder zoombar machen
Modifikatoren sind Standard-Kotlin-Objekte. Erstellen Sie einen Modifier, indem Sie eine der Funktionen der Klasse Modifier
aufrufen:
@Composable private fun Greeting(name: String) { Column(modifier = Modifier.padding(24.dp)) { Text(text = "Hello,") Text(text = name) } }
Sie können diese Funktionen verketten, um sie zu kombinieren:
@Composable private fun Greeting(name: String) { Column( modifier = Modifier .padding(24.dp) .fillMaxWidth() ) { Text(text = "Hello,") Text(text = name) } }
Im obigen Code werden verschiedene Modifikatorfunktionen zusammen verwendet.
- Mit
padding
wird um ein Element herum Platz geschaffen. - Mit
fillMaxWidth
wird festgelegt, dass das Composable die maximale Breite einnimmt, die ihm vom übergeordneten Element zugewiesen wird.
Es wird empfohlen, dass alle Ihre Composables einen modifier
-Parameter akzeptieren und diesen Modifier an das erste untergeordnete Element übergeben, das UI ausgibt.
Dadurch wird Ihr Code wiederverwendbarer und sein Verhalten vorhersehbarer und intuitiver. Weitere Informationen finden Sie in den Compose API-Richtlinien unter Elements accept and respect a Modifier parameter (Elemente akzeptieren und berücksichtigen einen Modifier-Parameter).
Reihenfolge der Modifikatoren ist wichtig
Die Reihenfolge der Änderungsfunktionen ist wichtig. Da jede Funktion Änderungen an der Modifier
vornimmt, die von der vorherigen Funktion zurückgegeben wurde, wirkt sich die Reihenfolge auf das Endergebnis aus. Sehen wir uns ein Beispiel an:
@Composable fun ArtistCard(/*...*/) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { // rest of the implementation } }
Im obigen Code ist der gesamte Bereich klickbar, einschließlich des umgebenden Abstands, da der padding
-Modifikator nach dem clickable
-Modifikator angewendet wurde. Wenn die Reihenfolge der Modifizierer umgekehrt wird, reagiert der von padding
hinzugefügte Leerraum nicht auf Nutzereingaben:
@Composable fun ArtistCard(/*...*/) { val padding = 16.dp Column( Modifier .padding(padding) .clickable(onClick = onClick) .fillMaxWidth() ) { // rest of the implementation } }
Integrierte Modifikatoren
Jetpack Compose bietet eine Liste integrierter Modifikatoren, mit denen Sie ein Composable-Element dekorieren oder erweitern können. Hier sind einige häufig verwendete Modifikatoren, mit denen Sie Ihre Layouts anpassen können.
padding
und size
Standardmäßig umschließen in Compose bereitgestellte Layouts ihre untergeordneten Elemente. Sie können jedoch eine Größe mit dem Modifikator size
festlegen:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image(/*...*/) Column { /*...*/ } } }
Die angegebene Größe wird möglicherweise nicht berücksichtigt, wenn sie nicht den Einschränkungen des übergeordneten Layouts entspricht. Wenn die Größe der zusammensetzbaren Funktion unabhängig von den eingehenden Einschränkungen festgelegt werden soll, verwenden Sie den Modifier requiredSize
:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image( /*...*/ modifier = Modifier.requiredSize(150.dp) ) Column { /*...*/ } } }
In diesem Beispiel ist die Höhe von Image
auch dann 150.dp
, wenn der übergeordnete height
auf 100.dp
festgelegt ist, da der Modifikator requiredSize
Vorrang hat.
Wenn ein untergeordnetes Layout die gesamte vom übergeordneten Element zulässige Höhe einnehmen soll, fügen Sie den Modifier fillMaxHeight
hinzu. Compose bietet auch fillMaxSize
und fillMaxWidth
:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image( /*...*/ modifier = Modifier.fillMaxHeight() ) Column { /*...*/ } } }
Wenn Sie ein Element mit Innenabstand umgeben möchten, legen Sie den Modifikator padding
fest.
Wenn Sie über einer Text-Baseline einen Innenabstand hinzufügen möchten, um einen bestimmten Abstand vom oberen Rand des Layouts zur Baseline zu erzielen, verwenden Sie den Modifikator paddingFromBaseline
:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text( text = artist.name, modifier = Modifier.paddingFromBaseline(top = 50.dp) ) Text(artist.lastSeenOnline) } } }
Offset
Wenn Sie ein Layout relativ zu seiner ursprünglichen Position positionieren möchten, fügen Sie den Modifikator offset
hinzu und legen Sie den Offset auf der x- und y-Achse fest.
Offsets können positiv oder nicht positiv sein. Der Unterschied zwischen padding
und offset
besteht darin, dass das Hinzufügen von offset
zu einem Composable seine Abmessungen nicht ändert:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text(artist.name) Text( text = artist.lastSeenOnline, modifier = Modifier.offset(x = 4.dp) ) } } }
Der Modifikator offset
wird horizontal entsprechend der Layoutrichtung angewendet.
In einem von links nach rechts ausgerichteten Kontext verschiebt ein positiver offset
-Wert das Element nach rechts, in einem von rechts nach links ausgerichteten Kontext nach links.
Wenn Sie einen Offset festlegen möchten, ohne die Layoutrichtung zu berücksichtigen, sehen Sie sich den Modifier absoluteOffset
an. Dort wird das Element bei einem positiven Offsetwert immer nach rechts verschoben.
Der Modifikator offset
bietet zwei Überladungen: offset
, die die Offsets als Parameter verwendet, und offset
, die eine Lambda-Funktion verwendet.
Ausführlichere Informationen dazu, wann die einzelnen Optionen verwendet werden sollten und wie Sie die Leistung optimieren können, finden Sie im Abschnitt Compose-Leistung – Lesevorgänge so lange wie möglich aufschieben.
Sicherheit von Bereichen in Compose
In Compose gibt es Modifikatoren, die nur verwendet werden können, wenn sie auf untergeordnete Elemente bestimmter Composables angewendet werden. In Compose wird dies durch benutzerdefinierte Bereiche erzwungen.
Wenn Sie beispielsweise ein untergeordnetes Element so groß wie das übergeordnete Element Box
machen möchten, ohne die Größe von Box
zu ändern, verwenden Sie den Modifikator matchParentSize
. matchParentSize
ist nur in BoxScope
verfügbar.
Daher kann es nur für ein untergeordnetes Element innerhalb eines Box
-übergeordneten Elements verwendet werden.
Durch die Bereichssicherheit wird verhindert, dass Sie Modifikatoren hinzufügen, die in anderen Composables und Bereichen nicht funktionieren. So sparen Sie Zeit, die Sie sonst für das Ausprobieren verschiedener Optionen benötigen würden.
Mit bereichsbezogenen Modifikatoren werden Eltern über bestimmte Informationen benachrichtigt, die sie über ihr Kind wissen sollten. Sie werden auch häufig als übergeordnete Datenmodifikatoren bezeichnet. Die internen Abläufe unterscheiden sich von denen der Allzweckmodifikatoren, aber aus Nutzersicht spielen diese Unterschiede keine Rolle.
matchParentSize
in Box
Wie oben erwähnt, können Sie mit dem Modifikator matchParentSize
ein untergeordnetes Layout auf die Größe eines übergeordneten Box
festlegen, ohne die Größe des Box
zu ändern.
Beachten Sie, dass matchParentSize
nur innerhalb eines Box
-Bereichs verfügbar ist. Das bedeutet, dass es nur für direkte untergeordnete Elemente von Box
-Composables gilt.
Im Beispiel unten übernimmt das untergeordnete Element Spacer
seine Größe vom übergeordneten Element Box
, das wiederum seine Größe vom größten untergeordneten Element, in diesem Fall ArtistCard
, übernimmt.
@Composable fun MatchParentSizeComposable() { Box { Spacer( Modifier .matchParentSize() .background(Color.LightGray) ) ArtistCard() } }
Wenn fillMaxSize
anstelle von matchParentSize
verwendet würde, würde Spacer
den gesamten verfügbaren Platz einnehmen, der dem übergeordneten Element zugewiesen ist. Dadurch würde sich das übergeordnete Element ausdehnen und den gesamten verfügbaren Platz einnehmen.
weight
in Row
und Column
Wie Sie im vorherigen Abschnitt zu Abstand und Größe gesehen haben, wird die Größe einer Composable-Funktion standardmäßig durch den Inhalt definiert, den sie umschließt. Mit dem weight
-Modifier, der nur in RowScope
und ColumnScope
verfügbar ist, können Sie die Größe einer Composable-Funktion so festlegen, dass sie innerhalb des übergeordneten Elements flexibel ist.
Sehen wir uns ein Row
an, das zwei Box
-Composables enthält.
Das erste Feld hat den doppelten weight
des zweiten Felds und ist daher doppelt so breit. Da die Row
210.dp
breit ist, ist die erste Box
140.dp
breit und die zweite 70.dp
:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.fillMaxWidth() ) { Image( /*...*/ modifier = Modifier.weight(2f) ) Column( modifier = Modifier.weight(1f) ) { /*...*/ } } }
Modifikatoren extrahieren und wiederverwenden
Mehrere Modifier können verkettet werden, um ein Composable zu gestalten oder zu erweitern. Diese Kette wird über die Modifier
-Schnittstelle erstellt, die eine geordnete, unveränderliche Liste einzelner Modifier.Elements
darstellt.
Jedes Modifier.Element
steht für ein einzelnes Verhalten, z. B. Layout-, Zeichen- und Grafikverhalten, alle gestenbezogenen Verhaltensweisen, Fokus- und Semantikverhalten sowie Geräteeingabeereignisse. Die Reihenfolge ist wichtig: Modifikatorelemente, die zuerst hinzugefügt werden, werden auch zuerst angewendet.
Manchmal kann es sinnvoll sein, dieselben Modifier-Ketteninstanzen in mehreren Composables wiederzuverwenden, indem Sie sie in Variablen extrahieren und in höhere Bereiche verschieben. Das kann aus mehreren Gründen die Lesbarkeit von Code verbessern oder die Leistung Ihrer App steigern:
- Die Neuzuweisung der Modifikatoren wird bei der Neuzusammenstellung von Composables, die sie verwenden, nicht wiederholt.
- Modifikator-Chains können potenziell sehr lang und komplex sein. Wenn Sie dieselbe Instanz einer Chain wiederverwenden, kann die Compose-Laufzeit die Arbeitslast beim Vergleichen reduzieren.
- Diese Extraktion fördert die Übersichtlichkeit, Konsistenz und Wartungsfreundlichkeit des Codes in der gesamten Codebasis.
Best Practices für die Wiederverwendung von Modifikatoren
Erstellen Sie eigene Modifier
-Ketten und extrahieren Sie sie, um sie in mehreren zusammensetzbaren Komponenten wiederzuverwenden. Es ist völlig in Ordnung, nur einen Modifier zu speichern, da es sich dabei um datenähnliche Objekte handelt:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp)
Modifikatoren extrahieren und wiederverwenden, wenn sich der Status häufig ändert
Wenn sich der Status in Composables häufig ändert, z. B. bei Animationsstatus oder scrollState
, kann es zu einer erheblichen Anzahl von Neukompositionen kommen. In diesem Fall werden Ihre Modifikatoren bei jeder Neuzusammenstellung und möglicherweise für jeden Frame zugewiesen:
@Composable fun LoadingWheelAnimation() { val animatedState = animateFloatAsState(/*...*/) LoadingWheel( // Creation and allocation of this modifier will happen on every frame of the animation! modifier = Modifier .padding(12.dp) .background(Color.Gray), animatedState = animatedState ) }
Stattdessen können Sie dieselbe Instanz des Modifikators erstellen, extrahieren und wiederverwenden und sie so an die zusammensetzbare Funktion übergeben:
// Now, the allocation of the modifier happens here: val reusableModifier = Modifier .padding(12.dp) .background(Color.Gray) @Composable fun LoadingWheelAnimation() { val animatedState = animateFloatAsState(/*...*/) LoadingWheel( // No allocation, as we're just reusing the same instance modifier = reusableModifier, animatedState = animatedState ) }
Nicht bereichsbezogene Modifikatoren extrahieren und wiederverwenden
Modifikatoren können entweder nicht oder auf eine bestimmte Komponente beschränkt sein. Bei Modifikatoren ohne Bereich können Sie sie ganz einfach als einfache Variablen außerhalb von Composables extrahieren:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) @Composable fun AuthorField() { HeaderText( // ... modifier = reusableModifier ) SubtitleText( // ... modifier = reusableModifier ) }
Das kann besonders in Kombination mit Lazy Layouts von Vorteil sein. In den meisten Fällen sollten alle Ihre Artikel, die möglicherweise eine erhebliche Menge ausmachen, genau dieselben Modifikatoren haben:
val reusableItemModifier = Modifier .padding(bottom = 12.dp) .size(216.dp) .clip(CircleShape) @Composable private fun AuthorList(authors: List<Author>) { LazyColumn { items(authors) { AsyncImage( // ... modifier = reusableItemModifier, ) } } }
Bereichsbezogene Modifikatoren extrahieren und wiederverwenden
Wenn Sie es mit Modifikatoren zu tun haben, die auf bestimmte Composables beschränkt sind, können Sie sie auf die höchstmögliche Ebene extrahieren und bei Bedarf wiederverwenden:
Column(/*...*/) { val reusableItemModifier = Modifier .padding(bottom = 12.dp) // Align Modifier.Element requires a ColumnScope .align(Alignment.CenterHorizontally) .weight(1f) Text1( modifier = reusableItemModifier, // ... ) Text2( modifier = reusableItemModifier // ... ) // ... }
Sie sollten die extrahierten, bereichsbezogenen Modifizierer nur an die direkten untergeordneten Elemente mit demselben Bereich übergeben. Weitere Informationen dazu, warum das wichtig ist, finden Sie im Abschnitt Umfangssicherheit in Compose:
Column(modifier = Modifier.fillMaxWidth()) { // Weight modifier is scoped to the Column composable val reusableItemModifier = Modifier.weight(1f) // Weight will be properly assigned here since this Text is a direct child of Column Text1( modifier = reusableItemModifier // ... ) Box { Text2( // Weight won't do anything here since the Text composable is not a direct child of Column modifier = reusableItemModifier // ... ) } }
Weitere Verkettung extrahierter Modifikatoren
Sie können die extrahierten Modifikatorfolgen weiter verketten oder anhängen, indem Sie die Funktion .then()
aufrufen:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) // Append to your reusableModifier reusableModifier.clickable { /*...*/ } // Append your reusableModifier otherModifier.then(reusableModifier)
Die Reihenfolge der Modifikatoren ist wichtig.
Weitere Informationen
Hier finden Sie eine vollständige Liste der Modifikatoren mit ihren Parametern und Bereichen.
Weitere Übungen zur Verwendung von Modifikatoren finden Sie im Codelab zu grundlegenden Layouts in Compose oder im Repository „Now in Android“.
Weitere Informationen zu benutzerdefinierten Modifikatoren und dazu, wie Sie sie erstellen, finden Sie in der Dokumentation unter Benutzerdefinierte Layouts – Layoutmodifikator verwenden.
Empfehlungen für dich
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Grundlagen des Compose-Layouts
- Editor-Aktionen {:#editor-actions}
- Benutzerdefinierte Layouts {:#custom-layouts }