Dettaglio elenco è un pattern di UI costituito da un layout a due riquadri in cui un riquadro presenta un elenco di elementi e un altro riquadro mostra i dettagli degli elementi selezionati dall'elenco.
Il pattern è particolarmente utile per le applicazioni che forniscono informazioni approfondite sugli elementi di raccolte di grandi dimensioni, ad esempio un client di posta che contiene un elenco di email e i contenuti dettagliati di ogni messaggio. List-detail può essere utilizzato anche per percorsi meno critici, ad esempio per suddividere le preferenze dell'app in un elenco di categorie con le preferenze per ogni categoria nel riquadro dei dettagli.


Implementare il pattern elenco-dettagli con NavigableListDetailPaneScaffold
NavigableListDetailPaneScaffold
è un composable che semplifica l'implementazione di un layout di elenco dettagliato in Jetpack Compose. Avvolge ListDetailPaneScaffold
e
aggiunge animazioni di navigazione e Indietro predittive integrate.
Uno scafo elenco dettagliato supporta fino a tre riquadri:
- Riquadro elenco: mostra una raccolta di elementi.
- Riquadro dei dettagli: mostra i dettagli di un elemento selezionato.
- Riquadro aggiuntivo (facoltativo): fornisce ulteriore contesto, se necessario.
La struttura si adatta in base alle dimensioni della finestra:
- Nelle finestre di grandi dimensioni, i riquadri dell'elenco e dei dettagli vengono visualizzati uno accanto all'altro.
- Nelle finestre piccole è visibile un solo riquadro alla volta, che cambia man mano che gli utenti navigano.
Dichiarare le dipendenze
NavigableListDetailPaneScaffold
fa parte della libreria di navigazione adattativa Material 3.
Aggiungi le tre dipendenze correlate seguenti al file build.gradle
della tua app o del tuo modulo:
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: componenti di base di basso livello come
HingeInfo
ePosture
- adaptive-layout: layout adattivi come
ListDetailPaneScaffold
eSupportingPaneScaffold
- adaptive-navigation: composabili per la navigazione all'interno e tra riquadri, nonché layout adattabili che supportano la navigazione per impostazione predefinita, come
NavigableListDetailPaneScaffold
eNavigableSupportingPaneScaffold
Assicurati che il progetto includa compose-material3-adaptive versione 1.1.0-beta1 o successive.
Attivare il gesto Indietro predittivo
Per attivare le animazioni Indietro predittive in Android 15 o versioni precedenti, devi attivare il supporto del gesto Indietro predittivo. Per attivare la funzionalità, aggiungi
android:enableOnBackInvokedCallback="true"
al tag <application>
o
singoli tag <activity>
all'interno del file AndroidManifest.xml
. Per ulteriori informazioni, consulta Attivare il gesto di scambio predittivo.
Se la tua app ha come target Android 16 (livello API 36) o versioni successive, il pulsante Indietro predittivo è attivo per impostazione predefinita.
Utilizzo di base
Implementa NavigableListDetailPaneScaffold
come segue:
- Utilizza un corso che rappresenti i contenuti selezionati. Utilizza una classe
Parcelable
per supportare il salvataggio e il ripristino dell'elemento dell'elenco selezionato. Utilizza il plug-in kotlin-parcelize per generare il codice per te. - Crea un
ThreePaneScaffoldNavigator
conrememberListDetailPaneScaffoldNavigator
.
Questo navigatore viene utilizzato per spostarsi tra i riquadri elenco, dei dettagli e aggiuntivi. Dichiarando un tipo generico, il navigatore monitora anche lo stato della struttura (ovvero quale MyItem
viene visualizzato). Poiché questo tipo è frazionabile, lo stato può essere salvato e ripristinato dal navigatore per gestire automaticamente le modifiche alla configurazione.
Passa il navigatore al composable
NavigableListDetailPaneScaffold
.Fornisci l'implementazione del riquadro degli elenchi al
NavigableListDetailPaneScaffold
. UtilizzaAnimatedPane
per applicare le animazioni predefinite dei riquadri durante la navigazione. Quindi, usaThreePaneScaffoldNavigator
per andare al riquadro dei dettagli,ListDetailPaneScaffoldRole.Detail
e visualizzare l'elemento passato.Includi l'implementazione del riquadro dei dettagli in
NavigableListDetailPaneScaffold
.
Al termine della navigazione, currentDestination
contiene il riquadro a cui è passata l'app, inclusi i contenuti visualizzati nel riquadro. La proprietà contentKey
è dello stesso tipo specificato nella chiamata originale, quindi puoi accedere
a tutti i dati che devi visualizzare.
- Se vuoi, modifica
defaultBackBehavior
inNavigableListDetailPaneScaffold
. Per impostazione predefinita,NavigableListDetailPaneScaffold
utilizzaPopUntilScaffoldValueChange
perdefaultBackBehavior
.
Se la tua app richiede un pattern di navigazione a ritroso diverso, puoi sostituire questo comportamento specificando un'altra opzione BackNavigationBehavior
.
BackNavigationBehavior
opzioni
La sezione seguente utilizza l'esempio di un'app email con un elenco di email in un riquadro e una visualizzazione dettagliata nell'altro.
PopUntilScaffoldValueChange
(predefinita e consigliata nella maggior parte dei casi)
Questo comportamento si concentra sulle modifiche alla struttura generale del layout. In una configurazione con più riquadri, la modifica dei contenuti dell'email nel riquadro dettagliato non altera la struttura di layout sottostante. Di conseguenza, il pulsante Indietro potrebbe uscire dall'app o dal grafo di navigazione corrente perché non è presente alcuna modifica del layout a cui tornare nel contesto corrente. In un layout a riquadro singolo, premendo Indietro vengono ignorate le modifiche ai contenuti all'interno della visualizzazione dettagliata e si torna alla visualizzazione elenco, poiché si tratta di una modifica chiara del layout.
Considera gli esempi seguenti:
- Visualizzazione a più riquadri:stai visualizzando un'email (elemento 1) nel riquadro dei dettagli. Se fai clic su un'altra email (elemento 2), il riquadro dei dettagli viene aggiornato, ma i riquadri elenco e dettagli rimangono visibili. Se premi Indietro, potresti uscire dall'app o dal flusso di navigazione corrente.
- Riquadro singolo: visualizzi l'elemento 1, quindi l'elemento 2. Premendo Indietro, tornerai direttamente al riquadro dell'elenco email.
Utilizzalo se vuoi che gli utenti percepiscano transizioni di layout distinte con ogni azione di riavvolgimento.

PopUntilContentChange
Questo comportamento dà la priorità ai contenuti visualizzati. Se visualizzi l'elemento 1 e poi l'elemento 2, premendo Indietro tornerai all'elemento 1, indipendentemente dal layout.
Considera gli esempi seguenti:
- Multi-pannello:visualizzi l'elemento 1 nel riquadro dei dettagli, quindi fai clic sull'elemento 2 nell'elenco. Il riquadro dei dettagli viene aggiornato. Se premi Indietro, il riquadro dei dettagli viene ripristinato all'elemento 1.
- Riquadro singolo:si verifica la stessa inversione dei contenuti.
Utilizzala quando l'utente si aspetta di tornare ai contenuti visualizzati in precedenza con l'azione Indietro.

PopUntilCurrentDestinationChange
Questo comportamento fa apparire la pila precedente finché la destinazione di navigazione corrente non cambia. Questo vale anche per i layout a riquadro singolo e multiplo.
Considera gli esempi seguenti:
Indipendentemente dal fatto che tu stia utilizzando un layout a riquadro singolo o multiplo, premendo Indietro lo stato attivo verrà spostato sempre dall'elemento di navigazione evidenziato alla destinazione precedente. Nella nostra app email, l'indicazione visiva del riquadro selezionato verrà spostata.
Utilizzalo quando mantenere un'indicazione visiva chiara della navigazione corrente è fondamentale per l'esperienza utente.

PopLatest
Questa opzione rimuove solo la destinazione più recente dal backstack. Utilizza questa opzione per tornare indietro senza saltare gli stati intermedi.
Dopo aver implementato questi passaggi, il codice dovrebbe avere il seguente aspetto:
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) } } }, )