List-detail è un pattern UI costituito da un layout a due riquadri, in cui un riquadro presenta un elenco di elementi e un altro riquadro visualizza i dettagli degli elementi selezionati dall'elenco.
Il pattern è particolarmente utile per le applicazioni che forniscono informazioni approfondite sugli elementi di grandi raccolte, ad esempio un client di posta che ha un elenco di email e i contenuti dettagliati di ogni messaggio email. L'attributo elenco dettaglio può essere utilizzato anche per percorsi meno critici, come la suddivisione delle preferenze delle app in un elenco di categorie con le preferenze per ogni categoria nel riquadro dei dettagli.
Implementa pattern UI con ListDetailPaneScaffold
ListDetailPaneScaffold
è un componibile che semplifica l'implementazione
del pattern elenco-dettagli nella tua app. Uno scaffold elenco-dettaglio può essere composto da fino a
tre riquadri: un riquadro dell'elenco, un riquadro dei dettagli e un riquadro aggiuntivo facoltativo. Lo scaffold gestisce i calcoli dello spazio sullo schermo. Quando le dimensioni dello schermo sono sufficienti, il riquadro dei dettagli viene visualizzato accanto al riquadro dell'elenco. Su schermi di piccole dimensioni, lo scaffold passa automaticamente alla visualizzazione dell'elenco o del riquadro dei dettagli a schermo intero.
![Un riquadro dei dettagli visualizzato accanto alla pagina dell'elenco.](https://developer.android.com/static/develop/ui/compose/images/layouts/adaptive/list-detail-2.png?hl=it)
![Dopo aver selezionato un elemento, il riquadro dei dettagli occupa l'intero schermo.](https://developer.android.com/static/develop/ui/compose/images/layouts/adaptive/list-detail-1.png?hl=it)
Dichiara le dipendenze
ListDetailPaneScaffold
fa parte della libreria di layout adattivi di Material 3.
La tua app deve includere dipendenze per tre librerie Material 3 correlate:
- Adattiva: componenti di base di basso livello come
HingeInfo
ePosture
- Layout adattivo: layout adattivi come
ListDetailPaneScaffold
eSupportingPaneScaffold
- Navigazione adattiva: elementi componibili per la navigazione all'interno e tra i riquadri
Aggiungi le dipendenze al file build.gradle
della tua app o del tuo modulo:
Kotlin
implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-alpha12") implementation("androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha12") implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha12")
Alla moda
implementation 'androidx.compose.material3.adaptive:adaptive:1.0.0-alpha12' implementation 'androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha12' implementation 'androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha12'
Utilizzo di base
Implementa ListDetailPaneScaffold
nel seguente modo:
Utilizza una classe che rappresenti i contenuti da selezionare. Questo corso deve essere
Parcelable
per supportare il salvataggio e il ripristino dell'elemento dell'elenco selezionato. Utilizza il plug-in kotlin-parcelize per generare il codice automaticamente.@Parcelize class MyItem(val id: Int) : Parcelable
Crea un
ThreePaneScaffoldNavigator
conrememberListDetailPaneScaffoldNavigator
e aggiungi unBackHandler
. Questo navigatore viene utilizzato per spostarsi tra l'elenco, i dettagli e i riquadri aggiuntivi. Se dichiara un tipo generico, il navigatore monitora anche lo stato dello scaffold, ovvero quello che viene visualizzato daMyItem
. Poiché questo tipo è parcelabile, lo stato può essere salvato e ripristinato dal navigatore per gestire automaticamente le modifiche alla configurazione.BackHandler
supporta la navigazione indietro utilizzando il gesto o il pulsante Indietro di sistema. Il comportamento previsto del pulsante Indietro per unListDetailPaneScaffold
dipende dalle dimensioni della finestra e dal valore dello scaffold attuale. SeListDetailPaneScaffold
è in grado di supportare il ripristino dello stato attuale, il valore dicanNavigateBack()
ètrue
e consente di attivareBackHandler
.val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
Passa il
scaffoldState
danavigator
al componibileListDetailPaneScaffold
.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
Fornisci l'implementazione del riquadro elenco a
ListDetailPaneScaffold
. UtilizzaAnimatedPane
per applicare le animazioni predefinite del riquadro durante la navigazione. Poi usaThreePaneScaffoldNavigator
per accedere al riquadro dei dettagliListDetailPaneScaffoldRole.Detail
e visualizzare l'elemento passato.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) } ) } }, // ... )
Includi l'implementazione del riquadro dei dettagli in
ListDetailPaneScaffold
. Al termine della navigazione,currentDestination
contiene il riquadro a cui è stata visitata la tua app, inclusi i contenuti visualizzati al suo interno. La proprietàcontent
è dello stesso tipo specificato nella chiamata di memorizzazione originale (MyItem
in questo esempio), quindi puoi accedere alla proprietà anche per tutti i dati che devi visualizzare.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane { navigator.currentDestination?.content?.let { MyDetails(it) } } }, )
Dopo aver implementato i passaggi precedenti, il codice dovrebbe essere simile al seguente:
val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) }, ) } }, detailPane = { AnimatedPane { // Show the detail pane content if selected item is available navigator.currentDestination?.content?.let { MyDetails(it) } } }, )