Wenn Sie auf einem Gerät mit Android 15 oder höher das SDK 35 oder höher verwenden, wird Ihre App randlos angezeigt. Das Fenster erstreckt sich über die gesamte Breite und Höhe des Displays, indem es hinter den Systemleisten gezeichnet wird. Zu den Systemleisten gehören die Statusleiste, die Titelleiste und die Navigationsleiste.
Viele Apps haben eine obere App-Leiste. Die obere App-Leiste sollte bis zum oberen Bildschirmrand reichen und hinter der Statusleiste angezeigt werden. Optional kann die obere App-Leiste auf die Höhe der Statusleiste verkleinert werden, wenn der Inhalt gescrollt wird.
Viele Apps haben auch eine untere App-Leiste oder eine untere Navigationsleiste. Diese Balken sollten sich auch bis zum unteren Bildschirmrand erstrecken und hinter der Navigationsleiste angezeigt werden. Andernfalls sollten Apps scrollbare Inhalte hinter der Navigationsleiste anzeigen.
Beachten Sie beim Implementieren eines randlosen Layouts in Ihrer App Folgendes:
- Randlose Anzeige aktivieren
- Adaptive Layouts implementieren, um die Nutzerfreundlichkeit auf verschiedenen Formfaktoren zu optimieren
- Visuelle Überschneidungen beheben
- Scrims hinter den Systemleisten anzeigen
Randlose Anzeige aktivieren
Wenn Ihre App auf SDK 35 oder höher ausgerichtet ist, wird die randlose Anzeige auf Geräten mit Android 15 oder höher automatisch aktiviert.
Wenn Sie das Edge-to-Edge-Display in früheren Android-Versionen aktivieren möchten, rufen Sie enableEdgeToEdge manuell in onCreate Ihrer Activity auf.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.enableEdgeToEdge(window)
...
}
Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowCompat.enableEdgeToEdge(getWindow());
...
}
Standardmäßig macht enableEdgeToEdge() die Systemleisten transparent, außer im Navigationsmodus mit 3 Schaltflächen, in dem die Navigationsleiste einen halbtransparenten Hintergrund erhält. Die Farben der Systemsymbole und des Scrims werden an das helle oder dunkle Design des Systems angepasst.
Wenn Sie die randlose Anzeige in Ihrer App ohne die Funktion enableEdgeToEdge() aktivieren möchten, lesen Sie den Hilfeartikel Randlose Anzeige manuell einrichten.
Überschneidungen mit Insets verarbeiten
Einige Ansichten Ihrer App werden möglicherweise hinter den Systemleisten dargestellt, wie in Abbildung 3 zu sehen.
Sie können Überlappungen vermeiden, indem Sie auf Insets reagieren, die angeben, welche Teile des Bildschirms sich mit der System-UI wie der Navigationsleiste oder der Statusleiste überschneiden. „Überschneiden“ kann bedeuten, dass die App über dem Inhalt angezeigt wird, aber es kann auch bedeuten, dass die App über System-Gesten informiert wird.
Folgende Arten von Insets gelten für die randlose Anzeige Ihrer App:
Systemleisten-Insets:Am besten für Ansichten, die antippbar sind und nicht visuell von den Systemleisten verdeckt werden dürfen.
Display-Aussparungen:für Bereiche, in denen aufgrund der Form des Geräts eine Display-Aussparung vorhanden sein kann.
System-Gesten-Insets:für Bereiche zur Bedienung über Gesten, die vom System verwendet werden und Vorrang vor Ihrer App haben.
Systemleisten-Insets
Systemleisten-Insets sind die am häufigsten verwendeten Insets. Sie stellen den Bereich dar, in dem die System-UI auf der Z-Achse über Ihrer App angezeigt wird. Sie eignen sich am besten, um Ansichten in Ihrer App zu verschieben oder zu füllen, die antippbar sind und nicht von den Systemleisten verdeckt werden dürfen.
Beispielsweise wird der unverankerte Aktionsbutton (UAB) in Abbildung 3 teilweise von der Navigationsleiste verdeckt:
Wenn Sie diese Art von visueller Überschneidung im Gesten- oder Schaltflächenmodus vermeiden möchten, können Sie die Ränder der Ansicht mit getInsets(int) und WindowInsetsCompat.Type.systemBars() vergrößern.
Das folgende Codebeispiel zeigt, wie Sie Systemleisten-Abstände implementieren:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left bottomMargin = insets.bottom rightMargin = insets.right } // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
Wenn Sie diese Lösung auf das Beispiel in Abbildung 3 anwenden, kommt es im Schaltflächenmodus zu keiner visuellen Überschneidung, wie in Abbildung 4 dargestellt:
Dasselbe gilt für die Bedienung über Gesten, wie in Abbildung 5 zu sehen:
Einzüge für Display-Aussparung
Einige Geräte haben Display-Aussparungen. In der Regel befindet sich der Ausschnitt oben auf dem Bildschirm und ist in der Statusleiste enthalten. Wenn sich das Display im Querformat befindet, kann sich der Ausschnitt am vertikalen Rand befinden. Je nachdem, welche Inhalte deine App auf dem Display anzeigt, solltest du Padding implementieren, um Display-Aussparungen zu vermeiden, da Apps standardmäßig in der Display-Aussparung dargestellt werden.
Viele App-Bildschirme zeigen beispielsweise eine Liste von Elementen an. Listenelemente dürfen nicht durch die Display-Aussparung oder die Systemleisten verdeckt werden.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
Bestimmen Sie den Wert von WindowInsetsCompat, indem Sie das logische or der Systemleisten und der Display-Aussparungstypen verwenden.
Legen Sie clipToPadding auf RecyclerView fest, damit das Padding mit den Listenelementen gescrollt wird. So können die Elemente hinter die Systemleisten verschoben werden, wenn der Nutzer scrollt, wie im folgenden Beispiel gezeigt.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
System-Gesten-Insets
System-Gesten-Insets stellen die Bereiche des Fensters dar, in denen System-Gesten Vorrang vor Ihrer App haben. Diese Bereiche sind in Abbildung 6 orange dargestellt:
Wie bei den Systemleisten-Insets können Sie auch bei den System-Gesten-Insets eine Überlappung vermeiden, indem Sie getInsets(int) mit WindowInsetsCompat.Type.systemGestures() verwenden.
Verwenden Sie diese Insets, um wischbare Ansichten von den Rändern wegzubewegen oder zu verschieben. Zu den häufigsten Anwendungsfällen gehören Ansichten am unteren Rand, Wischgesten in Spielen und Karussells, die mit ViewPager2 implementiert werden.
Unter Android 10 oder höher enthalten die Einsätze für System-Gesten einen unteren Einsatz für die Startbildschirm-Geste sowie einen linken und rechten Einsatz für die Zurück-Gesten:
Das folgende Codebeispiel zeigt, wie Sie Insets für System-Gesten implementieren:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Materialkomponenten
Viele ansichtsbasierte Android-Materialkomponenten (com.google.android.material) verarbeiten Insets automatisch, darunter BottomAppBar, BottomNavigationView, NavigationRailView und NavigationView.
AppBarLayout verarbeitet Insets jedoch nicht automatisch. Fügen Sie android:fitsSystemWindows="true" hinzu, um obere Insets zu verarbeiten.
Informationen zum Umgang mit Insets mit Material-Komponenten in Compose
Abwärtskompatible Inset-Verteilung
Wenn du verhindern möchtest, dass Insets an untergeordnete Ansichten weitergeleitet werden, und ein übermäßiges Padding vermeiden möchtest, kannst du Insets mit der Konstante WindowInsetsCompat.CONSUMED nutzen. Auf Geräten mit Android 10 (API-Level 29 und niedriger) werden Insets jedoch nach dem Aufruf von WindowInsetsCompat.CONSUMED nicht an gleichgeordnete Elemente gesendet. Das kann zu unbeabsichtigten visuellen Überschneidungen führen.
Wenn Sie sichergehen möchten, dass Insets für alle unterstützten Android-Versionen an gleichgeordnete Elemente gesendet werden, verwenden Sie ViewGroupCompat#installCompatInsetsDispatch, bevor Sie Insets nutzen. Diese Funktion ist in AndroidX Core und Core-ktx 1.16.0-alpha01 und höher verfügbar.
Kotlin
// Use the i.d. assigned to your layout's root view, e.g. R.id.main val rootView = findViewById(R.id.main) // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView)
Java
// Use the i.d. assigned to your layout's root view, e.g. R.id.main LinearLayout rootView = findViewById(R.id.main); // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView);
Immersiver Modus
Manche Inhalte lassen sich am besten im Vollbildmodus wiedergeben, um dem Nutzer ein intensiveres Erlebnis zu bieten. Mit den Bibliotheken WindowInsetsController und WindowInsetsControllerCompat können Sie die Systemleisten für den immersiven Modus ausblenden:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
Weitere Informationen zur Implementierung dieser Funktion findest du unter Systemleisten für den immersiven Modus ausblenden.
Symbole in der Systemleiste
Durch den Aufruf von enableEdgeToEdge wird sichergestellt, dass die Farben der Symbole in der Systemleiste aktualisiert werden, wenn sich das Design des Geräts ändert.
Wenn du das Edge-to-Edge-Layout verwendest, musst du möglicherweise die Farben der Symbole in der Systemleiste manuell aktualisieren, damit sie sich vom Hintergrund deiner App abheben. So erstellen Sie beispielsweise helle Symbole für die Statusleiste:
Kotlin
WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = false
Java
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
Schutz der Systemleiste
Wenn Ihre App auf SDK 35 oder höher ausgerichtet ist, wird die randlose Anzeige erzwungen.
Die Systemstatusleiste und die Leiste für die Bedienung über Gesten sind transparent, die Leiste für die Bedienung über 3 Schaltflächen ist jedoch durchscheinend. Rufen Sie enableEdgeToEdge auf, um die Abwärtskompatibilität zu gewährleisten.
Die Standardeinstellungen des Systems sind jedoch möglicherweise nicht für alle Anwendungsfälle geeignet. In den Designrichtlinien für Android-Systemleisten und im Edge-to-Edge-Design findest du Informationen dazu, ob du transparente oder transluzente Systemleisten verwenden solltest.
Transparente Systemleisten erstellen
Erstellen Sie eine transparente Statusleiste, indem Sie Android 15 (SDK 35) oder höher als Ziel festlegen oder enableEdgeToEdge() mit Standardargumenten für frühere Versionen aufrufen.
Erstellen Sie eine transparente Navigationsleiste für die Bedienung über Gesten, indem Sie Android 15 oder höher als Ziel festlegen oder enableEdgeToEdge() mit Standardargumenten für frühere Versionen aufrufen. Für die Navigationsleiste mit drei Schaltflächen legen Sie Window.setNavigationBarContrastEnforced auf false fest. Andernfalls wird ein durchscheinender Scrim angewendet.
Durchscheinende Systemleisten erstellen
So erstellen Sie eine transparente Statusleiste:
- Aktualisieren Sie die
androidx-core-Abhängigkeit auf 1.16.0-beta01 oder höher. - Verpacken Sie Ihr XML-Layout in
androidx.core.view.insets.ProtectionLayoutund weisen Sie eine ID zu. - Greifen Sie programmatisch auf die
ProtectionLayoutzu, um Schutzmaßnahmen festzulegen. Geben Sie dazu die Seite und einenGradientProtectionfür die Statusleiste an.
<androidx.core.view.insets.ProtectionLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_protection" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/item_list" android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent"> <!--items--> </ScrollView> </androidx.core.view.insets.ProtectionLayout>
findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color paneBackgroundColor ) ) )
Achte darauf, dass der an GradientProtection übergebene ColorInt mit dem Hintergrund des Inhalts übereinstimmt. Beispielsweise kann ein Listen-Detail-Layout, das auf einem faltbaren Gerät angezeigt wird, unterschiedliche GradientProtections in verschiedenen Farben für den Listen- und den Detailbereich haben.
Erstelle keine transparente Navigationsleiste für die Bedienung über Gesten. So erstellen Sie eine durchscheinende Navigationsleiste mit drei Schaltflächen:
- Wenn Ihr Layout bereits in einem
ProtectionView-Element enthalten ist, können Sie ein zusätzlichesColorProtection- oderGradientProtection-Element an diesetProtections-Methode übergeben. Prüfen Sie vorher, obwindow.isNavigationBarContrastEnforced = false. - Andernfalls legen Sie
window.isNavigationBarContrastEnforced = truefest.
Weitere Tipps
Zusätzliche Tipps zum Umgang mit Insets.
Scrollbare Inhalte im Vollbildmodus anzeigen
Prüfe, ob das letzte Listenelement in RecyclerView oder NestedScrollView durch die Systemleisten verdeckt wird. Behandle dazu die Insets und setze clipToPadding auf false.
Das folgende Video zeigt ein RecyclerView mit deaktiviertem (links) und aktiviertem (rechts) Edge-to-Edge-Display:
Ein Codebeispiel finden Sie in den Code-Snippets im Abschnitt Dynamische Listen mit RecyclerView erstellen.
Vollbilddialoge randlos anzeigen
Wenn Sie Dialogfelder im Vollbildmodus randlos anzeigen möchten, rufen Sie enableEdgeToEdge für das Dialogfeld auf.
Kotlin
class MyAlertDialogFragment : DialogFragment() {
override fun onStart(){
super.onStart()
dialog?.window?.let { WindowCompat.enableEdgeToEdge(it) }
}
...
}
Java
public class MyAlertDialogFragment extends DialogFragment {
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
Window window = dialog.getWindow();
if (window != null) {
WindowCompat.enableEdgeToEdge(window);
}
}
}
...
}
Zusätzliche Ressourcen
Weitere Informationen zum Edge-to-Edge-Modus finden Sie in den folgenden Referenzen.
Blogs
- Tipps zur Verarbeitung von Insets für die Edge-to-Edge-Erzwingung in Android 15
- WindowInsets – Listener für Layouts
Design
Weitere Dokumentation
Videos