Wenn Ihre App die vollständige Kontrolle darüber haben soll, wo Inhalte gerendert werden, folgen Sie dieser Einrichtungsanleitung. Wenn Sie diese Schritte nicht ausführen, werden in Ihrer App möglicherweise schwarze oder einfarbige Hintergründe hinter der System-UI angezeigt oder die Animationen werden nicht synchron mit der Softwaretastatur ausgeführt.
- Richten Sie Ihre App auf Android 15 (API‑Level 35) oder höher aus, um Edge-to-Edge-Darstellung auf Android 15 und höher zu erzwingen. Ihre App wird hinter der System-UI angezeigt. Sie können die Benutzeroberfläche Ihrer App anpassen, indem Sie Insets verarbeiten.
- Rufen Sie optional
enableEdgeToEdge()
inActivity.onCreate()
auf, damit Ihre App auch in früheren Android-Versionen randlos angezeigt wird. Legen Sie
android:windowSoftInputMode="adjustResize"
imAndroidManifest.xml
-Eintrag Ihrer Aktivität fest. Mit dieser Einstellung kann Ihre App die Größe des Software-IME als Insets empfangen. So können Sie das entsprechende Layout und Padding anwenden, wenn das IME in Ihrer App ein- und ausgeblendet wird.<!-- In your AndroidManifest.xml file: --> <activity android:name=".ui.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.MyApplication" android:exported="true">
Compose-APIs verwenden
Sobald Ihre Aktivität alle Insets übernimmt, können Sie Compose-APIs verwenden, um dafür zu sorgen, dass Inhalte nicht verdeckt werden und interaktive Elemente sich nicht mit der System-UI überschneiden. Diese APIs synchronisieren auch das Layout Ihrer App mit Änderungen an den Insets.
Dies ist beispielsweise die einfachste Methode, 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 safeDrawing
-Fenstereinsetzungen als Padding um den gesamten Inhalt der App angewendet. Dadurch wird zwar sichergestellt, dass interaktive Elemente sich nicht mit der System-UI überschneiden, aber auch, dass kein Teil der App hinter der System-UI gerendert wird, um einen Edge-to-Edge-Effekt zu erzielen. Damit das gesamte Fenster genutzt werden kann, müssen Sie die Insets 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. Daher werden auch alle Ihre Layouts, die diese Insets verwenden, automatisch animiert, wenn sich die Inset-Werte ändern.
Es gibt zwei primäre Möglichkeiten, diese Inset-Typen zum Anpassen Ihrer zusammensetzbaren Layouts zu verwenden: Padding- und Inset-Größenmodifikatoren.
Abstandsmodifikatoren
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
wendet die angegebenen Fenstereinsätze als Padding an, genau wie Modifier.padding
.
Mit Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
werden beispielsweise die Insets für den sicheren Zeichenbereich als Padding auf alle 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. Für die anderen Inset-Typen gibt es analoge Modifikatoren.
Größenmodifikatoren für Insets
Mit den folgenden Modifizierern wird ein Betrag für die Fenstereinsätze angewendet, indem die Größe der Komponente auf die Größe der Einsätze festgelegt wird:
Wendet die Startseite von „windowInsets“ als Breite an (wie |
|
Wendet die Endseite von „windowInsets“ als Breite an (z. B. |
|
Wendet die Oberseite von „windowInsets“ als Höhe an (wie |
|
|
Wendet die Unterseite von „windowInsets“ als Höhe an (z. B. |
Diese Modifikatoren sind besonders nützlich, um die Größe eines Spacer
festzulegen, das den Platz von Insets einnimmt:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Verbrauch von Insets
Die Inset-Padding-Modifikatoren (windowInsetsPadding
und Hilfsfunktionen wie safeDrawingPadding
) verwenden automatisch den Teil der Insets, der als Padding angewendet wird. Wenn Sie tiefer in den Kompositionsbaum gehen, wissen die verschachtelten Inset-Padding-Modifier und die Inset-Größen-Modifier, dass ein Teil der Insets bereits von äußeren Inset-Padding-Modifiern verwendet wurde. Sie vermeiden es, denselben Teil der Insets mehr als einmal zu verwenden, was zu viel zusätzlichem Leerraum führen würde.
Mit Größenmodifikatoren für Insets wird auch vermieden, dass derselbe Teil von Insets mehr als einmal verwendet wird, wenn Insets bereits verwendet wurden. Da sie ihre Größe jedoch direkt ändern, werden keine Insets verwendet.
Wenn Sie Padding-Modifikatoren schachteln, ändert sich die Menge an Padding, die auf die einzelnen Composables angewendet wird, automatisch.
Im selben LazyColumn
-Beispiel wie zuvor wird die Größe des LazyColumn
mit dem Modifikator imePadding
angepasst. Im LazyColumn
wird das letzte Element auf die Höhe des unteren Rands der Systemleisten festgelegt:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Wenn die IME geschlossen ist, wird durch den imePadding()
-Modifikator kein Padding angewendet, da die IME keine Höhe hat. Da für den Modifikator imePadding()
kein Padding angewendet wird, werden keine Insets verwendet und die Höhe von Spacer
entspricht der Größe der Unterseite der Systemleisten.
Wenn die IME geöffnet wird, werden die IME-Insets animiert, um der Größe der IME zu entsprechen, und der imePadding()
-Modifikator beginnt, das untere Padding anzuwenden, um die Größe von LazyColumn
beim Öffnen der IME anzupassen. Wenn der Modifikator imePadding()
mit dem Anwenden des unteren Innenabstands beginnt, wird auch dieser Betrag an Insets verwendet. Daher beginnt die Höhe von Spacer
zu sinken, da ein Teil des Abstands für die Systemleisten bereits durch den Modifikator imePadding()
angewendet wurde. Wenn der Modifizierer imePadding()
einen unteren Innenabstand anwendet, der größer als die Systemleisten ist, ist die Höhe von Spacer
null.
Wenn die IME geschlossen wird, kehren sich die Änderungen um: Das Spacer
beginnt, sich von einer Höhe von null zu erweitern, sobald das imePadding()
weniger als die Unterseite der Systemleisten anwendet, bis das Spacer
schließlich der Höhe der Unterseite der Systemleisten entspricht, wenn die IME vollständig animiert wurde.
TextField
.Dieses Verhalten wird durch die Kommunikation zwischen allen windowInsetsPadding
-Modifikatoren erreicht und kann auf verschiedene andere Arten beeinflusst werden.
Modifier.consumeWindowInsets(insets: WindowInsets)
verwendet Insets auf dieselbe Weise wie Modifier.windowInsetsPadding
, wendet die verwendeten Insets jedoch nicht als Padding an. Dies ist in Kombination mit den Größenmodifikatoren für Insets nützlich, um Geschwisterkomponenten darüber zu informieren, dass bereits eine bestimmte Anzahl von Insets 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 dem Argument WindowInsets
, verwendet aber ein beliebiges PaddingValues
. Das ist nützlich, um Kinder darüber zu informieren, wenn das Padding oder der Abstand durch einen anderen Mechanismus als die Inset-Padding-Modifizierer bereitgestellt wird, z. B. durch ein normales Modifier.padding
oder Spacer mit fester Höhe:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
Wenn die Roh-Fenstereinsätze ohne Verbrauch benötigt werden, verwenden Sie die WindowInsets
-Werte direkt oder verwenden Sie WindowInsets.asPaddingValues()
, um eine PaddingValues
der Einsätze zurückzugeben, die nicht vom Verbrauch betroffen sind.
Aufgrund der folgenden Einschränkungen sollten Sie jedoch nach Möglichkeit die Padding- und Größenmodifikatoren für Window Insets verwenden.
Insets und Jetpack Compose-Phasen
Compose verwendet die zugrunde liegenden AndroidX-Kern-APIs, um Insets zu aktualisieren und zu animieren. Diese APIs verwenden die zugrunde liegenden Plattform-APIs, die Insets verwalten. Aufgrund dieses Plattformverhaltens haben Insets eine besondere Beziehung zu den Phasen von Jetpack Compose.
Die Werte für Insets werden nach der Kompositionsphase, aber vor der Layoutphase aktualisiert. Das bedeutet, dass beim Lesen des Werts von Insets in einer Komposition in der Regel 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. So wird sichergestellt, dass die Inset-Werte für denselben Frame verwendet werden, für den sie aktualisiert werden.