„Listen-Detailansicht“ ist ein UI-Muster, das aus einem Layout mit zwei Bereichen besteht. In einem Bereich wird eine Liste mit Elementen angezeigt und im anderen Bereich die Details der Elemente, die in der Liste ausgewählt wurden.
Das Muster ist besonders nützlich für Anwendungen, die detaillierte Informationen zu Elementen großer Sammlungen bieten, z. B. ein E‑Mail-Client mit einer Liste von E‑Mails und dem detaillierten Inhalt jeder E‑Mail-Nachricht. Die Listen-Detailansicht kann auch für weniger kritische Pfade verwendet werden, z. B. um App-Einstellungen in eine Liste von Kategorien zu unterteilen, wobei die Einstellungen für jede Kategorie im Detailbereich angezeigt werden.
Muster „Liste – Detail“ mit NavigableListDetailPaneScaffold implementieren
NavigableListDetailPaneScaffold ist eine komponierbare Funktion, die die Implementierung eines Layouts vom Typ „Listen-Detailansicht“ in Jetpack Compose vereinfacht. Es umschließt ListDetailPaneScaffold und fügt integrierte Navigation und Animationen für intelligente „Zurück“-Gesten hinzu.
Ein Listen-Detailansicht-Scaffold 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): Hier werden bei Bedarf zusätzliche Informationen angezeigt.
Das Scaffold wird an die Fenstergröße angepasst:
- In großen Fenstern werden die Bereiche „Liste“ und „Detail“ 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 von 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'
- adaptive: Low-Level-Bausteine wie
HingeInfoundPosture - adaptive-layout: Adaptive Layouts wie
ListDetailPaneScaffoldundSupportingPaneScaffold - adaptive-navigation: Composables für die Navigation innerhalb und zwischen Bereichen sowie adaptive Layouts, die standardmäßig Navigation unterstützen, z. B.
NavigableListDetailPaneScaffoldundNavigableSupportingPaneScaffold
Achten Sie darauf, dass Ihr Projekt die Version 1.1.0-beta1 oder höher von compose-material3-adaptive enthält.
Intelligente „Zurück“-Geste aktivieren
Wenn Sie Animationen für intelligente „Zurück“-Gesten in Android 15 oder niedriger aktivieren möchten, müssen Sie die Unterstützung für die intelligente „Zurück“-Geste aktivieren. Fügen Sie dazu
android:enableOnBackInvokedCallback="true" dem <application> Tag oder
einzelnen <activity> Tags in der Datei AndroidManifest.xml hinzu. Weitere Informationen finden Sie unter Intelligente „Zurück“-Geste aktivieren.
Wenn Ihre App auf Android 16 (API-Level 36) oder höher ausgerichtet ist, ist die intelligente „Zurück“-Geste standardmäßig aktiviert.
Grundlegende Nutzung
Implementieren Sie NavigableListDetailPaneScaffold so:
- Verwenden Sie eine Klasse, die den ausgewählten Inhalt darstellt. Verwenden Sie eine
ParcelableKlasse, um das Speichern und Wiederherstellen des ausgewählten Listenelements zu unterstützen. Verwenden Sie das Kotlin-Parcelize-Plug-in, um den Code für Sie zu generieren. - Erstellen Sie mit
rememberListDetailPaneScaffoldNavigatoreinenThreePaneScaffoldNavigator.
Mit diesem Navigator können Sie zwischen den Bereichen „Liste“, „Detail“ und „Zusätzlich“ wechseln. Durch Deklarieren eines generischen Typs verfolgt der Navigator auch den Status des Scaffolds (d. h., welches 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 das Composable
NavigableListDetailPaneScaffold.Geben Sie die Implementierung des Listenbereichs für
NavigableListDetailPaneScaffoldan. Verwenden SieAnimatedPane, um die Standardanimationen für Bereiche während der Navigation anzuwenden. Verwenden Sie dannThreePaneScaffoldNavigator, um zum DetailbereichListDetailPaneScaffoldRole.Detailzu navigieren und das übergebene Element anzuzeigen.Fügen Sie die Implementierung des Detailbereichs in
NavigableListDetailPaneScaffoldein.
Nach Abschluss der Navigation enthält currentDestination den Bereich, zu dem Ihre App navigiert ist, einschließlich der Inhalte, die im Bereich angezeigt werden. Die Property contentKey hat denselben Typ, der im ursprünglichen Aufruf angegeben wurde. So können Sie auf alle Daten zugreifen, die Sie anzeigen müssen.
- Optional können Sie das
defaultBackBehaviorinNavigableListDetailPaneScaffoldändern. Standardmäßig verwendetNavigableListDetailPaneScaffoldPopUntilScaffoldValueChangefürdefaultBackBehavior.
Wenn Ihre App ein anderes Muster für die Rückwärtsnavigation erfordert, können Sie dieses Verhalten überschreiben, indem Sie eine andere Option für BackNavigationBehavior 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 Bereich verwendet.
PopUntilScaffoldValueChange (Standard und in den meisten Fällen empfohlen)
Dieses Verhalten konzentriert sich auf Änderungen an der Gesamtstruktur des Layouts. Bei einer Konfiguration mit mehreren Bereichen ändert sich durch das Ändern des E‑Mail-Inhalts im Detailbereich nicht die zugrunde liegende Layoutstruktur. Daher kann die App oder der aktuelle Navigationsgraph mit dem Button „Zurück“ beendet werden, da es im aktuellen Kontext keine Layoutänderung gibt, zu der zurückgekehrt werden kann. Bei 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 klare Layoutänderung darstellt.
Betrachten Sie hierzu folgende Beispiele:
- Mehrere Bereiche:Sie sehen eine E‑Mail (Element 1) im Detailbereich. Wenn Sie auf eine andere E‑Mail (Element 2) klicken, wird der Detailbereich aktualisiert, aber die Bereiche „Liste“ und „Detail“ bleiben sichtbar. Durch Drücken der Zurück-Taste kann die App oder der aktuelle Navigationsfluss beendet werden.
- Ein Bereich:Sie sehen Element 1 und dann Element 2. Wenn Sie die Zurück-Taste drücken, 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
Bei diesem Verhalten wird der angezeigte Inhalt priorisiert. Wenn Sie Element 1 und dann Element 2 ansehen, wird durch Drücken der Zurück-Taste zu Element 1 zurückgekehrt, unabhängig vom Layout.
Betrachten Sie hierzu folgende Beispiele:
- Mehrere Bereiche:Sie sehen Element 1 im Detailbereich und klicken dann in der Liste auf Element 2. Der Detailbereich wird aktualisiert. Durch Drücken der Zurück-Taste wird im Detailbereich wieder Element 1 angezeigt.
- Ein Bereich:Dieselbe Inhaltsänderung erfolgt.
Verwenden Sie diese Option, wenn Nutzer erwarten, dass sie mit der Zurück-Aktion zum zuvor angesehenen Inhalt zurückkehren.
PopUntilCurrentDestinationChange
Bei diesem Verhalten wird der Back-Stack so lange entfernt, 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 der Fokus durch Drücken der Zurück-Taste immer vom hervorgehobenen Navigationselement zum vorherigen Ziel verschoben. In unserer E‑Mail-App ändert sich dadurch die visuelle Darstellung des ausgewählten Bereichs.
Verwenden Sie diese Option, wenn eine klare visuelle Darstellung der aktuellen Navigation für die Nutzererfahrung entscheidend ist.
PopLatest
Mit dieser Option wird nur das letzte Ziel aus dem Back-Stack 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:
NavigableListDetailPaneScaffold( navigator = navigator, listPane = { AnimatedPane { ListContent( words = sampleWords, selectionState = navigator.currentDestination?.contentKey?.let { SelectionVisibilityState.ShowSelection(it) } ?: SelectionVisibilityState.NoSelection, onWordClick = { word -> scope.launch { navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, word) } }, animatedVisibilityScope = this@AnimatedPane, sharedTransitionScope = this@SharedTransitionLayout ) } }, detailPane = { AnimatedPane { DetailContent( definedWord = navigator.currentDestination?.contentKey, animatedVisibilityScope = this@AnimatedPane, sharedTransitionScope = this@SharedTransitionLayout, onClosePane = { scope.launch { navigator.navigateBack( backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) } } ) } }