In Compose können Sie mehrere Modifikatoren miteinander verknüpfen, um das Erscheinungsbild eines Composeables zu ändern. Diese Modifikatorketten können sich auf die Einschränkungen auswirken, die an Kompositionen übergeben werden und die Breite und Höhe definieren.
Auf dieser Seite wird beschrieben, wie sich verkette Modifikatoren auf Einschränkungen und damit auf die Analyse und Platzierung von Composeable-Elementen auswirken.
Modifikatoren im UI-Baum
Um zu verstehen, wie sich Modifikatoren gegenseitig beeinflussen, ist es hilfreich, sich vorzustellen, wie sie im UI-Baum erscheinen, der in der Kompositionphase generiert wird. Weitere Informationen finden Sie im Abschnitt Komposition.
Im UI-Baum können Sie Modifikatoren als Wrapper-Knoten für die Layoutknoten visualisieren:
Wenn du einem Composeable mehrere Modifikatoren hinzufügst, entsteht eine Kette von Modifikatoren. Wenn Sie mehrere Modifikatoren verketten, umschließt jeder Modifikatorknoten den Rest der Kette und den Layoutknoten darin. Wenn Sie beispielsweise einen clip
- und einen size
-Modifikator verketten, umschließt der clip
-Modifikatorknoten den size
-Modifikatorknoten, der wiederum den Image
-Layoutknoten umschließt.
In der Layoutphase bleibt der Algorithmus, der den Baum durchläuft, gleich, aber auch jeder Modifikatorknoten wird besucht. So kann ein Modifikator die Größenanforderungen und die Platzierung des Modifikators oder Layoutknotens ändern, um den Text einzufügen.
Wie in Abbildung 2 dargestellt, besteht die Implementierung der Image
- und Text
-Kompositen aus einer Kette von Modifikatoren, die einen einzelnen Layoutknoten umschließen. Die Implementierungen von Row
und Column
sind einfach Layoutknoten, die beschreiben, wie ihre untergeordneten Elemente angeordnet werden.
Zusammenfassung:
- Modifikatoren umschließen einen einzelnen Modifikator- oder Layoutknoten.
- Layoutknoten können mehrere untergeordnete Knoten anordnen.
In den folgenden Abschnitten wird beschrieben, wie Sie dieses mentale Modell verwenden können, um die Modifikatorverknüpfung zu analysieren und zu verstehen, wie sie die Größe von Composeables beeinflusst.
Einschränkungen in der Layoutphase
In der Layoutphase wird mit einem dreistufigen Algorithmus die Breite, Höhe und die X‑ und Y‑Koordinaten jedes Layoutknotens ermittelt:
- Untergeordnete Elemente messen: Ein Knoten misst seine untergeordneten Elemente, falls vorhanden.
- Eigene Größe festlegen: Anhand dieser Messungen entscheidet ein Knoten über seine eigene Größe.
- Untergeordnete Elemente platzieren: Jeder untergeordnete Knoten wird relativ zur Position eines Knotens platziert.
Constraints
helfen, die richtigen Größen für die Knoten in den ersten beiden Schritten des Algorithmus zu finden. Mit Einschränkungen werden die Mindest- und Höchstwerte für die Breite und Höhe eines Knotens definiert. Wenn der Knoten seine Größe festlegt, sollte die gemessene Größe in diesen Größenbereich fallen.
Arten von Einschränkungen
Eine Einschränkung kann eine der folgenden sein:
- Begrenzt: Der Knoten hat eine maximale und minimale Breite und Höhe.
- Unbegrenzt: Die Größe des Knotens ist nicht begrenzt. Die maximalen Werte für Breite und Höhe sind auf unendlich festgelegt.
- Genau: Der Knoten muss genau einer bestimmten Größe entsprechen. Die Mindest- und Höchstwerte sind auf denselben Wert festgelegt.
- Kombination: Der Knoten folgt einer Kombination der oben genannten Einschränkungstypen. Eine Einschränkung kann beispielsweise die Breite begrenzen, während eine unbegrenzte maximale Höhe zulässig ist, oder eine genaue Breite festlegen, aber eine begrenzte Höhe.
Im nächsten Abschnitt wird beschrieben, wie diese Einschränkungen von einem übergeordneten Element an ein untergeordnetes Element übergeben werden.
So werden Einschränkungen von übergeordneten Elementen an untergeordnete Elemente übergeben
Im ersten Schritt des Algorithmus, der unter Einschränkungen in der Layoutphase beschrieben wird, werden Einschränkungen im UI-Baum von übergeordneten Elementen an untergeordnete Elemente weitergegeben.
Wenn ein übergeordneter Knoten seine untergeordneten Knoten misst, stellt er jedem untergeordneten Knoten diese Einschränkungen zur Verfügung, damit er weiß, wie groß oder klein er sein darf. Wenn es dann seine eigene Größe festlegt, hält es sich auch an die Einschränkungen, die von seinen übergeordneten Elementen übergeben wurden.
Der Algorithmus funktioniert im Groben so:
- Um die tatsächliche Größe zu bestimmen, misst der Stammknoten im UI-Baum seine untergeordneten Elemente und leitet dieselben Einschränkungen an sein erstes untergeordnetes Element weiter.
- Wenn das untergeordnete Element ein Modifikator ist, der sich nicht auf die Messung auswirkt, werden die Einschränkungen an den nächsten Modifikator weitergeleitet. Die Einschränkungen werden unverändert an die Modifikatorkette übergeben, es sei denn, ein Modifikator wird erreicht, der sich auf die Analyse auswirkt. Die Einschränkungen werden dann entsprechend neu skaliert.
- Sobald ein Knoten erreicht wird, der keine untergeordneten Knoten hat (dies wird als „Blattknoten“ bezeichnet), wird seine Größe anhand der übergebenen Einschränkungen festgelegt und an das übergeordnete Element zurückgegeben.
- Das übergeordnete Element passt seine Einschränkungen anhand der Maße dieses untergeordneten Elements an und ruft sein nächstes untergeordnetes Element mit diesen angepassten Einschränkungen auf.
- Sobald alle untergeordneten Elemente eines übergeordneten Elements gemessen wurden, entscheidet der übergeordnete Knoten über seine eigene Größe und teilt dies seinem übergeordneten Element mit.
- So wird der gesamte Baum zuerst von oben nach unten durchlaufen. Schließlich haben sich alle Knoten für ihre Größe entschieden und der Messschritt ist abgeschlossen.
Ein ausführliches Beispiel finden Sie im Video Einschränkungen und Reihenfolge der Modifikatoren.
Modifikatoren, die sich auf Einschränkungen auswirken
Im vorherigen Abschnitt haben Sie erfahren, dass einige Modifikatoren die Größe von Einschränkungen beeinflussen können. In den folgenden Abschnitten werden bestimmte Modifikatoren beschrieben, die sich auf Einschränkungen auswirken.
size
-Modifikator
Mit dem Modifikator size
wird die bevorzugte Größe der Inhalte angegeben.
Beispielsweise sollte der folgende UI-Baum in einem Container mit einer Größe von 300dp
× 200dp
gerendert werden. Die Einschränkungen sind begrenzt. Die Breite darf zwischen 100dp
und 300dp
liegen und die Höhe zwischen 100dp
und 200dp
:
Mit dem Modifikator size
werden eingehende Einschränkungen an den übergebenen Wert angepasst.
In diesem Beispiel ist der Wert 150dp
:
Wenn die Breite und Höhe kleiner als die kleinste Einschränkungsgrenze oder größer als die größte Einschränkungsgrenze sind, entspricht der Modifikator den übergebenen Einschränkungen so genau wie möglich, wobei die übergebenen Einschränkungen eingehalten werden:
Die Verknüpfung mehrerer size
-Modifikatoren funktioniert nicht. Mit dem ersten size
-Modifikator werden sowohl die Mindest- als auch die Höchsteinschränkungen auf einen festen Wert festgelegt. Auch wenn der zweite Größenmodifikator eine kleinere oder größere Größe anfordert, muss er die genauen übergebenen Grenzen einhalten, sodass diese Werte nicht überschrieben werden:
requiredSize
-Modifikator
Verwenden Sie den Modifikator requiredSize
anstelle von size
, wenn der Knoten die eingehenden Einschränkungen überschreiben soll. Der requiredSize
-Modifikator ersetzt die eingehenden Einschränkungen und übergibt die von Ihnen angegebene Größe als genaue Grenzen.
Wenn die Größe wieder nach oben in den Baum übergeben wird, wird der untergeordnete Knoten im verfügbaren Bereich zentriert:
width
- und height
-Modifikatoren
Mit dem Modifizierer size
werden sowohl die Breite als auch die Höhe der Einschränkungen angepasst. Mit dem Modifikator width
können Sie eine feste Breite festlegen, die Höhe aber offen lassen.
Mit dem Modifikator height
können Sie auch eine feste Höhe festlegen, die Breite aber offen lassen:
sizeIn
-Modifikator
Mit dem Modifikator sizeIn
können Sie genaue Mindest- und Höchstwerte für Breite und Höhe festlegen. Verwenden Sie den Modifikator sizeIn
, wenn Sie die Einschränkungen genau steuern möchten.
Beispiele
In diesem Abschnitt wird die Ausgabe mehrerer Code-Snippets mit verketteten Modifikatoren gezeigt und erläutert.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Dieses Snippet führt zu folgender Ausgabe:
- Mit dem Modifikator
fillMaxSize
werden die Einschränkungen so geändert, dass sowohl die Mindestbreite als auch die Mindesthöhe auf den Maximalwert festgelegt werden:300dp
in der Breite und200dp
in der Höhe. - Auch wenn für den
size
-Modifikator eine Größe von50dp
verwendet werden soll, müssen die Mindesteinschränkungen für eingehende Nachrichten eingehalten werden. Der Modifikatorsize
gibt also auch die genauen Einschränkungsgrenzen von300
×200
aus und ignoriert dabei den im Modifikatorsize
angegebenen Wert. - Die
Image
folgt diesen Grenzen und meldet eine Größe von300
×200
, die bis zum Stamm des Baums weitergegeben wird.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Dieses Snippet führt zu folgender Ausgabe:
- Mit dem Modifikator
fillMaxSize
werden die Einschränkungen so angepasst, dass sowohl die Mindestbreite als auch die Mindesthöhe auf den Höchstwert festgelegt werden –300dp
in der Breite und200dp
in der Höhe. - Mit dem Modifikator
wrapContentSize
werden die Mindesteinschränkungen zurückgesetzt. WährendfillMaxSize
zu festen Einschränkungen führte, setztwrapContentSize
sie zurück auf begrenzte Einschränkungen. Der folgende Knoten kann jetzt wieder den gesamten Bereich einnehmen oder kleiner als der gesamte Bereich sein. - Mit dem Modifikator
size
werden die Einschränkungen auf die Mindest- und Höchstwerte von50
festgelegt. Image
wird in eine Größe von50
×50
aufgelöst und der Modifikatorsize
leitet diese weiter.- Der Modifikator
wrapContentSize
hat eine spezielle Eigenschaft. Das untergeordnete Element wird in die Mitte der verfügbaren Mindestgrenzen gesetzt, die ihm übergeben wurden. Die Größe, die an die übergeordneten Elemente gesendet wird, entspricht daher den Mindestgrenzwerten, die übergeben wurden.
Mit nur drei Modifikatoren können Sie eine Größe für das Composeable definieren und es im übergeordneten Element zentrieren.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Dieses Snippet führt zu folgender Ausgabe:
- Der
clip
-Modifikator ändert die Einschränkungen nicht.- Mit dem Modifikator
padding
werden die maximalen Einschränkungen gesenkt. - Mit dem Modifikator
size
werden alle Einschränkungen auf100dp
festgelegt. - Die
Image
entspricht diesen Einschränkungen und hat eine Größe von100
×100dp
. - Der Modifizierer
padding
fügt allen Größen10dp
hinzu, wodurch die gemeldete Breite und Höhe um20dp
erhöht wird. - In der Zeichenphase wirkt der
clip
-Modifikator auf ein Canvas von120
×120dp
ein. Es wird also eine Kreismaske dieser Größe erstellt. - Der Modifizierer
padding
fügt den Inhalt dann in allen Größen um10dp
ein, wodurch die Canvas-Größe um100dp
auf100
verringert wird. - Die
Image
wird in diesem Canvas gezeichnet. Das Bild wird anhand des ursprünglichen Kreises von120dp
zugeschnitten, sodass das Ergebnis nicht rund ist.
- Mit dem Modifikator