List-detail est un modèle d'UI qui se compose d'une mise en page à deux volets. L'un présente une liste d'éléments et l'autre affiche les détails des éléments sélectionnés dans la liste.
Ce modèle est particulièrement utile pour les applications qui fournissent des informations détaillées sur les éléments de grandes collections, par exemple, un client de messagerie qui comporte une liste d'e-mails et le contenu détaillé de chaque message. Le modèle liste/détails peut également être utilisé pour des chemins moins critiques, par exemple pour diviser les préférences de l'application en une liste de catégories, avec les préférences de chaque catégorie dans le volet Détails.


Implémenter le schéma Liste/Détail avec NavigableListDetailPaneScaffold
NavigableListDetailPaneScaffold
est un composable qui simplifie l'implémentation d'une mise en page liste/détails dans Jetpack Compose. Il encapsule ListDetailPaneScaffold
et ajoute des animations de navigation et de prévisualisation du Retour intégrées.
Une structure Liste/Détail peut comporter jusqu'à trois volets :
- Volet Liste : affiche une collection d'éléments.
- Volet Détails : affiche les détails d'un élément sélectionné.
- Volet supplémentaire (facultatif) : fournit un contexte supplémentaire si nécessaire.
L'échafaudage s'adapte en fonction de la taille de la fenêtre :
- Dans les grandes fenêtres, les volets de liste et de détails s'affichent côte à côte.
- Dans les petites fenêtres, un seul volet est visible à la fois, et il change à mesure que les utilisateurs naviguent.
Déclarer des dépendances
NavigableListDetailPaneScaffold
fait partie de la bibliothèque de navigation adaptative Material 3.
Ajoutez les trois dépendances associées suivantes au fichier build.gradle
de votre application ou module :
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 : blocs de construction de bas niveau tels que
HingeInfo
etPosture
- adaptive-layout : mises en page adaptatives telles que
ListDetailPaneScaffold
etSupportingPaneScaffold
- adaptive-navigation : composables pour naviguer dans et entre les volets, ainsi que des mises en page adaptatives qui prennent en charge la navigation par défaut, comme
NavigableListDetailPaneScaffold
etNavigableSupportingPaneScaffold
Assurez-vous que votre projet inclut compose-material3-adaptive version 1.1.0-beta1 ou version ultérieure.
Activer la prévisualisation du geste Retour
Pour activer les animations de prévisualisation du geste Retour dans Android 15 ou version antérieure, vous devez activer la prise en charge de la prévisualisation du geste Retour. Pour l'activer, ajoutez android:enableOnBackInvokedCallback="true"
à la balise <application>
ou aux balises <activity>
individuelles de votre fichier AndroidManifest.xml
. Pour en savoir plus, consultez Activer la prévisualisation du geste Retour.
Une fois que votre application cible Android 16 (niveau d'API 36) ou version ultérieure, la prévisualisation du Retour est activée par défaut.
Utilisation de base
Implémentez NavigableListDetailPaneScaffold
comme suit :
- Utilisez une classe qui représente le contenu sélectionné. Utilisez une classe
Parcelable
pour permettre l'enregistrement et la restauration de l'élément de liste sélectionné. Utilisez le plug-in kotlin-parcelize pour générer le code à votre place. - Créez un
ThreePaneScaffoldNavigator
avecrememberListDetailPaneScaffoldNavigator
.
Ce navigateur permet de passer de la liste aux volets "Détails" et "Plus". En déclarant un type générique, le navigateur suit également l'état du scaffold (c'est-à-dire le MyItem
affiché). Comme ce type est sérialisable, l'état peut être enregistré et restauré par le navigateur pour gérer automatiquement les modifications de configuration.
Transmettez le navigateur au composable
NavigableListDetailPaneScaffold
.Fournissez l'implémentation du volet de liste au
NavigableListDetailPaneScaffold
. UtilisezAnimatedPane
pour appliquer les animations de volet par défaut lors de la navigation. Utilisez ensuiteThreePaneScaffoldNavigator
pour accéder au volet d'informations,ListDetailPaneScaffoldRole.Detail
, et afficher l'élément transmis.Incluez l'implémentation de votre volet Détails dans
NavigableListDetailPaneScaffold
.
Une fois la navigation terminée, currentDestination
contient le volet vers lequel votre application a été redirigée, y compris le contenu affiché dans le volet. La propriété contentKey
est du même type que celui spécifié dans l'appel d'origine. Vous pouvez donc accéder à toutes les données que vous devez afficher.
- Vous pouvez également modifier le
defaultBackBehavior
dansNavigableListDetailPaneScaffold
. Par défaut,NavigableListDetailPaneScaffold
utilisePopUntilScaffoldValueChange
pourdefaultBackBehavior
.
Si votre application nécessite un autre modèle de navigation à l'arrière, vous pouvez remplacer ce comportement en spécifiant une autre option BackNavigationBehavior
.
Options BackNavigationBehavior
La section suivante utilise l'exemple d'une application de messagerie avec une liste d'e-mails dans un volet et une vue détaillée dans l'autre.
PopUntilScaffoldValueChange
(valeur par défaut et recommandée dans la plupart des cas)
Ce comportement se concentre sur les modifications apportées à la structure globale de la mise en page. Dans une configuration à plusieurs volets, la modification du contenu de l'e-mail dans le volet détaillé n'altère pas la structure de mise en page sous-jacente. Par conséquent, le bouton Retour peut quitter l'application ou le graphique de navigation actuel, car il n'y a pas de modification de mise en page à annuler dans le contexte actuel. Dans une mise en page à un seul volet, appuyer sur le bouton Retour permet de passer d'une modification de contenu à une autre dans la vue détaillée et de revenir à la vue Liste, car cela représente un changement de mise en page clair.
Exemples :
- Volet multiple : vous consultez un e-mail (élément 1) dans le volet d'informations. Si vous cliquez sur un autre e-mail (élément 2), le volet de détails est mis à jour, mais les volets de liste et de détails restent visibles. Appuyer sur le bouton Retour peut quitter l'application ou le flux de navigation actuel.
- Volet unique : vous affichez l'élément 1, puis l'élément 2. Si vous appuyez sur "Retour", vous revenez directement au volet de la liste des e-mails.
Utilisez-le lorsque vous souhaitez que les utilisateurs perçoivent des transitions de mise en page distinctes à chaque action de retour.

PopUntilContentChange
Ce comportement donne la priorité au contenu affiché. Si vous affichez l'élément 1, puis l'élément 2, le fait d'appuyer sur le bouton "Retour" vous ramènera à l'élément 1, quel que soit la mise en page.
Exemples :
- Volets multiples : vous affichez l'élément 1 dans le volet de détails, puis cliquez sur l'élément 2 dans la liste. Le volet Détails est mis à jour. Si vous appuyez sur le bouton Retour, le volet Détails est restauré sur l'élément 1.
- Volet unique : la même restauration de contenu se produit.
Utilisez-le lorsque votre utilisateur s'attend à revenir au contenu précédemment consulté avec l'action de retour.

PopUntilCurrentDestinationChange
Ce comportement supprime la pile "Retour" jusqu'à ce que la destination de navigation actuelle change. Cela s'applique aussi bien aux mises en page à un seul volet qu'à celles à plusieurs volets.
Exemples :
Que vous utilisiez une mise en page à un ou plusieurs volets, appuyer sur "Retour" déplacera toujours le focus de l'élément de navigation mis en surbrillance vers la destination précédente. Dans notre application de messagerie, cela signifie que l'indication visuelle du volet sélectionné se déplacera.
Utilisez cette option lorsque le maintien d'une indication visuelle claire de la navigation actuelle est essentiel pour l'expérience utilisateur.

PopLatest
Cette option ne supprime que la destination la plus récente de la pile "Retour". Utilisez cette option pour revenir en arrière sans ignorer les états intermédiaires.
Une fois ces étapes terminées, votre code doit se présenter comme suit :
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) } } }, )