„Liste/Details“ ist ein UI-Muster, das aus einem Layout mit zwei Bereichen besteht. In einem Bereich wird eine Liste mit Elementen angezeigt, im anderen die Details der Elemente, die aus der Liste ausgewählt wurden.
Das Muster ist besonders nützlich für Anwendungen, die detaillierte Informationen zu Elementen großer Sammlungen liefern, z. B. ein E‑Mail-Client mit einer Liste von E‑Mails und dem detaillierten Inhalt jeder E‑Mail. Die Listendetailansicht kann auch für weniger kritische Pfade verwendet werden, z. B. zum Aufteilen von App-Einstellungen in eine Liste von Kategorien mit den Einstellungen für jede Kategorie im Detailbereich.


Implementieren des List-Detail-Musters mit NavigableListDetailPaneScaffold
NavigableListDetailPaneScaffold
ist eine Composable-Funktion, die die Implementierung eines Listen-/Detail-Layouts in Jetpack Compose vereinfacht. Es umschließt ListDetailPaneScaffold
und fügt integrierte Navigation und Animationen für die intelligente „Zurück“-Geste hinzu.
Ein Listendetail-Gerüst unterstützt bis zu drei Bereiche:
- Listenbereich: Hier wird eine Sammlung von Elementen angezeigt.
- Detailbereich: Hier werden die Details eines ausgewählten Elements angezeigt.
- Zusätzlicher Bereich (optional): Bietet bei Bedarf zusätzlichen Kontext.
Das Gerüst passt sich an die Fenstergröße an:
- In großen Fenstern werden die Listen- und Detailbereiche nebeneinander angezeigt.
- In kleinen Fenstern ist jeweils nur ein Bereich sichtbar. Die Bereiche werden gewechselt, wenn Nutzer navigieren.
Abhängigkeiten deklarieren
NavigableListDetailPaneScaffold
ist Teil der adaptiven Navigationsbibliothek für Material 3.
Fügen Sie der Datei build.gradle
Ihrer App oder Ihres Moduls die folgenden drei zugehörigen Abhängigkeiten hinzu:
Kotlin
implementation("androidx.compose.material3.adaptive:adaptive") implementation("androidx.compose.material3.adaptive:adaptive-layout") implementation("androidx.compose.material3.adaptive:adaptive-navigation")
Groovy
implementation 'androidx.compose.material3.adaptive:adaptive' implementation 'androidx.compose.material3.adaptive:adaptive-layout' implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
- adaptiv: Low-Level-Bausteine wie
HingeInfo
undPosture
- adaptive-layout: Adaptive Layouts wie
ListDetailPaneScaffold
undSupportingPaneScaffold
- adaptive-navigation: Composables für die Navigation innerhalb und zwischen Bereichen sowie adaptive Layouts, die standardmäßig die Navigation unterstützen, z. B.
NavigableListDetailPaneScaffold
undNavigableSupportingPaneScaffold
Ihr Projekt muss compose-material3-adaptive Version 1.1.0-beta1 oder höher enthalten.
Intelligente „Zurück“-Touch-Geste aktivieren
Wenn Sie Animationen für die intelligente „Zurück“-Touchgeste in Android 15 oder niedriger aktivieren möchten, müssen Sie die Unterstützung für die intelligente „Zurück“-Touchgeste aktivieren. Fügen Sie dazu android:enableOnBackInvokedCallback="true"
dem Tag <application>
oder einzelnen <activity>
-Tags in Ihrer AndroidManifest.xml
-Datei hinzu. Weitere Informationen finden Sie unter Predictive Back-Geste aktivieren.
Sobald Ihre App auf Android 16 (API‑Level 36) oder höher ausgerichtet ist, ist die Funktion „Vorhersagende Zurück-Geste“ standardmäßig aktiviert.
Grundlegende Nutzung
Implementieren Sie NavigableListDetailPaneScaffold
so:
- Verwenden Sie eine Klasse, die die ausgewählten Inhalte darstellt. Verwenden Sie die Klasse
Parcelable
, um das Speichern und Wiederherstellen des ausgewählten Listenelements zu unterstützen. Verwenden Sie das kotlin-parcelize-Plug-in, um den Code generieren zu lassen. - Erstellen Sie eine
ThreePaneScaffoldNavigator
mitrememberListDetailPaneScaffoldNavigator
.
Mit diesem Navigator können Sie zwischen der Liste, dem Detailbereich und den zusätzlichen Bereichen wechseln. Durch die Deklaration eines generischen Typs verfolgt der Navigator auch den Status des Gerüsts (d. h. welche MyItem
angezeigt wird). Da dieser Typ parcelable ist, kann der Status vom Navigator gespeichert und wiederhergestellt werden, um Konfigurationsänderungen automatisch zu verarbeiten.
Übergeben Sie den Navigator an die zusammensetzbare Funktion
NavigableListDetailPaneScaffold
.Stellen Sie die Implementierung des Listenbereichs für
NavigableListDetailPaneScaffold
bereit. Verwenden SieAnimatedPane
, um die Standardanimationen für Bereiche während der Navigation anzuwenden. Verwenden Sie dannThreePaneScaffoldNavigator
, um zum DetailbereichListDetailPaneScaffoldRole.Detail
zu wechseln und das übergebene Element anzuzeigen.Fügen Sie die Implementierung des Detailbereichs in
NavigableListDetailPaneScaffold
ein.
Wenn die Navigation abgeschlossen ist, enthält currentDestination
den Bereich, zu dem Ihre App navigiert ist, einschließlich der im Bereich angezeigten Inhalte. Die contentKey
-Property hat denselben Typ wie im ursprünglichen Aufruf angegeben. Sie können also auf alle Daten zugreifen, die Sie anzeigen müssen.
- Ändern Sie optional
defaultBackBehavior
inNavigableListDetailPaneScaffold
. Standardmäßig verwendetNavigableListDetailPaneScaffold
PopUntilScaffoldValueChange
fürdefaultBackBehavior
.
Wenn Ihre App ein anderes Muster für die Zurück-Navigation erfordert, können Sie dieses Verhalten überschreiben, indem Sie eine andere BackNavigationBehavior
-Option angeben.
Optionen für BackNavigationBehavior
Im folgenden Abschnitt wird das Beispiel einer E‑Mail-App mit einer Liste von E‑Mails in einem Bereich und einer Detailansicht im anderen verwendet.
PopUntilScaffoldValueChange
(Standard und in den meisten Fällen empfohlen)
Dieses Verhalten bezieht sich auf Änderungen an der allgemeinen Layoutstruktur. Wenn Sie in einer Einrichtung mit mehreren Bereichen den E-Mail-Inhalt im Detailbereich ändern, wird die zugrunde liegende Layoutstruktur nicht geändert. Daher kann es sein, dass die App oder der aktuelle Navigationsgraph durch Drücken der Zurück-Schaltfläche beendet wird, da im aktuellen Kontext keine Layoutänderung rückgängig gemacht werden kann. In einem Layout mit einem Bereich werden durch Drücken der Zurück-Taste Inhaltsänderungen in der Detailansicht übersprungen und zur Listenansicht zurückgekehrt, da dies eine deutliche Layoutänderung darstellt.
Betrachten Sie hierzu folgende Beispiele:
- Mehrspaltig:Sie sehen sich eine E‑Mail (Element 1) im Detailbereich an. Wenn Sie auf eine andere E‑Mail (Punkt 2) klicken, wird der Detailbereich aktualisiert, aber die Listen- und Detailbereiche bleiben sichtbar. Durch Drücken der Zurück-Taste wird die App oder der aktuelle Navigationsvorgang möglicherweise beendet.
- Einzelbereich:Sie sehen zuerst Element 1 und dann Element 2. Wenn Sie auf „Zurück“ tippen, kehren Sie direkt zum Bereich mit der E‑Mail-Liste zurück.
Verwenden Sie diese Option, wenn Nutzer bei jeder Zurück-Aktion deutliche Layoutübergänge sehen sollen.

PopUntilContentChange
So wird der angezeigte Inhalt priorisiert. Wenn Sie sich zuerst Artikel 1 und dann Artikel 2 ansehen, gelangen Sie durch Drücken der Zurück-Taste wieder zu Artikel 1, unabhängig vom Layout.
Betrachten Sie hierzu folgende Beispiele:
- Mehrere Bereiche:Sie sehen sich Element 1 im Detailbereich an und klicken dann in der Liste auf Element 2. Der Detailbereich wird aktualisiert. Wenn Sie auf „Zurück“ drücken, wird der Detailbereich auf Element 1 zurückgesetzt.
- Einzelnes Feld:Es kommt zur selben Inhaltsreversion.
Verwenden Sie diese Option, wenn der Nutzer erwartet, mit der Zurück-Aktion zum zuvor angesehenen Inhalt zurückzukehren.

PopUntilCurrentDestinationChange
Dadurch wird der Backstack so lange geleert, bis sich das aktuelle Navigationsziel ändert. Dies gilt gleichermaßen für Layouts mit einem und mehreren Bereichen.
Betrachten Sie hierzu folgende Beispiele:
Unabhängig davon, ob Sie sich in einem Layout mit einem oder mehreren Bereichen befinden, wird durch Drücken der Zurück-Taste der Fokus immer vom hervorgehobenen Navigationselement zum vorherigen Ziel verschoben. In unserer E‑Mail-App bedeutet das, dass sich die visuelle Darstellung des ausgewählten Bereichs ändert.
Verwenden Sie diese Option, wenn eine klare visuelle Anzeige der aktuellen Navigation für die Nutzererfahrung entscheidend ist.

PopLatest
Bei dieser Option wird nur das letzte Ziel aus dem Backstack entfernt. Verwenden Sie diese Option für die Rückwärtsnavigation, ohne Zwischenzustände zu überspringen.
Nachdem Sie diese Schritte ausgeführt haben, sollte Ihr Code in etwa so aussehen:
val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem>() val scope = rememberCoroutineScope() NavigableListDetailPaneScaffold( navigator = scaffoldNavigator, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item scope.launch { scaffoldNavigator.navigateTo( ListDetailPaneScaffoldRole.Detail, item ) } }, ) } }, detailPane = { AnimatedPane { // Show the detail pane content if selected item is available scaffoldNavigator.currentDestination?.contentKey?.let { MyDetails(it) } } }, )