Sobald die Activity die Verarbeitung aller Insets übernommen hat, können Sie mit Compose APIs prüfen, ob Inhalte nicht verdeckt sind und interaktive Elemente sich nicht mit der System-UI überschneiden. Diese APIs synchronisieren auch das Layout Ihrer App mit Änderungen an den Insets.
Insets mit Padding- oder Größenmodifikatoren verarbeiten
Dies ist beispielsweise die einfachste Methode, um die Insets auf den Inhalt Ihrer gesamten App anzuwenden:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
In diesem Snippet werden die Fenstereinsätze safeDrawing als Padding um den gesamten Inhalt der App angewendet. Dadurch wird zwar verhindert, dass interaktive Elemente die System-UI überlappen, aber es bedeutet auch, dass kein Teil der App hinter der System-UI gezeichnet wird, um einen randlosen Effekt zu erzielen. Wenn Sie das gesamte Fenster optimal nutzen möchten, müssen Sie die Position der Einzüge für jeden Bildschirm oder jede Komponente einzeln anpassen.
Alle diese Inset-Typen werden automatisch mit IME-Animationen animiert, die auf API 21 zurückportiert wurden. Dadurch werden auch alle Layouts, die diese Insets verwenden, automatisch animiert, wenn sich die Inset-Werte ändern.
Es gibt drei Möglichkeiten, Insets zu verarbeiten, um Ihre zusammensetzbaren Layouts anzupassen:
Abstandsmodifikatoren
Modifier.windowInsetsPadding(windowInsets: WindowInsets) wendet die angegebenen Fenstereinzüge als Padding an, genau wie Modifier.padding.
Mit Modifier.windowInsetsPadding(WindowInsets.safeDrawing) werden beispielsweise die sicheren Zeichenbereiche als Padding auf allen vier Seiten angewendet.
Außerdem gibt es mehrere integrierte Dienstprogrammmethoden für die gängigsten Inset-Typen.
Modifier.safeDrawingPadding() ist eine solche Methode, die Modifier.windowInsetsPadding(WindowInsets.safeDrawing) entspricht. In der folgenden Tabelle sind die integrierten Padding-Modifikatoren und der jeweils angewendete WindowInsets-Typ aufgeführt:
Informationen dazu, was die einzelnen Inset-Typen abdecken, finden Sie unter Informationen zu Fenster-Insets.
Modifikatoren für die Größe des Insets
Mit den folgenden Modifikatoren wird ein bestimmter Fenster-Inset-Wert angewendet, indem die Größe der Komponente auf die Größe der Insets festgelegt wird:
Wendet die Startseite von windowInsets als Breite an (z. B. |
|
Wendet die Endseite von windowInsets als Breite an (wie |
|
Wendet die Oberseite von windowInsets als Höhe an (z. B. |
|
|
Wendet die Unterseite von windowInsets als Höhe an (z. B. |
Diese Modifikatoren sind besonders nützlich, um die Größe eines Spacer-Elements anzupassen, das den Platz von Insets einnimmt:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Inset-Verbrauch
Die Modifikatoren für das Padding von Insets (windowInsetsPadding und Hilfsprogramme wie safeDrawingPadding) nutzen automatisch den Teil der Insets, der als Padding angewendet wird. Wenn Sie tiefer in den Kompositionsbaum vordringen, wissen die verschachtelten Inset-Padding-Modifikatoren und die Inset-Größenmodifikatoren, dass ein Teil der Insets bereits von äußeren Inset-Padding-Modifikatoren verbraucht wurde. Sie vermeiden es, denselben Teil der Insets mehr als einmal zu verwenden, was zu viel zusätzlichen Platz beanspruchen würde.
Inset-Größenmodifikatoren vermeiden auch, dass derselbe Teil von Insets mehr als einmal verwendet wird, wenn Insets bereits verbraucht wurden. Da sie jedoch ihre Größe direkt ändern, verbrauchen sie selbst keine Insets.
Wenn Sie Padding-Modifikatoren verschachteln, ändert sich automatisch die Menge des Paddings, das auf jedes Compose-Element angewendet wird.
Im selben LazyColumn-Beispiel wie zuvor wird die Größe des LazyColumn durch den Modifikator imePadding angepasst. Im LazyColumn wird das letzte Element so dimensioniert, dass es der Höhe des unteren Bereichs der Systemleisten entspricht:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Wenn der IME geschlossen ist, wendet imePadding() kein Padding an. Folglich werden keine Insets verbraucht und die Höhe von Spacer entspricht der Höhe der unteren Systemleisten.
Wenn die Eingabemethode geöffnet wird, werden die IME-Insets animiert, um der Größe der Eingabemethode zu entsprechen. Der Modifikator imePadding() beginnt, einen unteren Abstand anzuwenden, um die Größe von LazyColumn beim Öffnen der Eingabemethode anzupassen. Wenn der Modifikator imePadding() beginnt, den unteren Abstand anzuwenden, beginnt er auch, diese Menge an Insets zu verbrauchen. Daher nimmt die Höhe des Spacer ab, da ein Teil des Abstands für die Systemleisten bereits durch den imePadding()-Modifikator angewendet wurde. Sobald der Modifikator imePadding() einen unteren Abstand anwendet, der größer als die Systemleisten ist, ist die Höhe von Spacer null.
Wenn die Eingabemethode geschlossen wird, werden die Änderungen umgekehrt: Die Spacer wird von der Höhe null erweitert, da imePadding() weniger als die unteren Systemleisten anwendet.
Schließlich entspricht die Höhe von Spacer der Höhe der Systemleisten, sobald die IME vollständig ausgeblendet ist.
TextField.Dieses Verhalten wird durch die Kommunikation zwischen allen windowInsetsPadding-Modifikatoren erreicht und kann auf verschiedene andere Arten beeinflusst werden.
Modifier.consumeWindowInsets(insets: WindowInsets) nutzt Insets auf dieselbe Weise wie Modifier.windowInsetsPadding, wendet die genutzten Insets aber nicht als Padding an. Dies ist in Kombination mit den Modifikatoren für die Inset-Größe nützlich, um gleichgeordneten Elementen mitzuteilen, dass eine bestimmte Anzahl von Insets bereits verwendet wurde:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) verhält sich sehr ähnlich wie die Version mit einem WindowInsets-Argument, nimmt aber einen beliebigen PaddingValues zur Verarbeitung an. Das ist nützlich, um untergeordnete Elemente zu informieren, wenn Padding oder Abstände durch einen anderen Mechanismus als die Inset-Padding-Modifikatoren bereitgestellt werden, z. B. durch ein gewöhnliches Modifier.padding oder Abstandshalter mit fester Höhe:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
Wenn die Rohwerte der Fenstereinzüge ohne Verbrauch benötigt werden, verwenden Sie die WindowInsets-Werte direkt oder verwenden Sie WindowInsets.asPaddingValues(), um eine PaddingValues der Einzüge zurückzugeben, die nicht vom Verbrauch betroffen sind.
Aufgrund der folgenden Einschränkungen sollten Sie jedoch nach Möglichkeit die Modifikatoren für das Padding und die Größe von Fenster-Insets verwenden.
Insets und Jetpack Compose-Phasen
Compose verwendet die zugrunde liegenden AndroidX-Core-APIs, um Insets zu aktualisieren und zu animieren. Diese verwenden die zugrunde liegenden Plattform-APIs, die Insets verwalten. Aufgrund dieses Plattformverhaltens haben Insets eine besondere Beziehung zu den Phasen von Jetpack Compose.
Der Wert von Insets wird nach der Kompositionsphase, aber vor der Layoutphase aktualisiert. Das bedeutet, dass beim Lesen des Werts von Insets in der Komposition im Allgemeinen ein Wert der Insets verwendet wird, der einen Frame zu spät ist. Die auf dieser Seite beschriebenen integrierten Modifikatoren sind so konzipiert, dass die Werte der Insets erst in der Layoutphase verwendet werden. Dadurch wird sichergestellt, dass die Inset-Werte im selben Frame verwendet werden, in dem sie aktualisiert werden.