Crea un layout elenco-dettagli

Elenco-dettagli è un pattern dell'interfaccia utente 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 dettagliate sugli elementi di grandi raccolte, ad esempio un client email che ha un elenco di email e il contenuto dettagliato di ogni messaggio email. L'elenco dettagliato può essere utilizzato anche per percorsi meno critici, ad esempio per dividere le preferenze dell'app in un elenco di categorie con le preferenze per ogni categoria nel riquadro dei dettagli.

Un riquadro dei dettagli visualizzato accanto alla pagina dell'elenco.
Figura 1. Quando è disponibile spazio sufficiente sullo schermo, il riquadro dei dettagli viene visualizzato accanto al riquadro dell'elenco.
Una volta selezionato un elemento, il riquadro dei dettagli occupa l'intera schermata.
Figura 2. Quando le dimensioni dello schermo sono limitate, il riquadro dei dettagli (dopo la selezione di un elemento) occupa tutto lo spazio.

Implementare il pattern elenco-dettaglio con NavigableListDetailPaneScaffold

NavigableListDetailPaneScaffold è un composable che semplifica l'implementazione di un layout elenco-dettagli in Jetpack Compose. Esegue il wrapping di ListDetailPaneScaffold e aggiunge animazioni di navigazione e Indietro predittivo integrate.

Uno scaffold elenco-dettagli supporta fino a tre riquadri:

  1. Riquadro Elenco: mostra una raccolta di elementi.
  2. Riquadro dei dettagli: mostra i dettagli di un elemento selezionato.
  3. Riquadro aggiuntivo (facoltativo): fornisce ulteriore contesto quando necessario.

La struttura si adatta in base alle dimensioni della finestra:

  • Nelle finestre grandi, 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 adattiva Material 3.

Aggiungi le seguenti tre dipendenze correlate 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'
  • adattivi: componenti di base di basso livello come HingeInfo e Posture
  • adaptive-layout: layout adattivi come ListDetailPaneScaffold e SupportingPaneScaffold
  • adaptive-navigation: componenti componibili per la navigazione all'interno e tra i riquadri, nonché layout adattivi che supportano la navigazione per impostazione predefinita, come NavigableListDetailPaneScaffold e NavigableSupportingPaneScaffold

Assicurati che il progetto includa compose-material3-adaptive versione 1.1.0-beta1 o successive.

Attivare il gesto Indietro predittivo

Per attivare le animazioni del gesto Indietro predittivo 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 ai singoli tag <activity> all'interno del file AndroidManifest.xml. Per ulteriori informazioni, consulta la sezione Attivare la navigazione predittiva.

Una volta che la tua app ha come target Android 16 (livello API 36) o versioni successive, la navigazione predittiva è attivata per impostazione predefinita.

Utilizzo di base

Implementa NavigableListDetailPaneScaffold nel seguente modo:

  1. Utilizza una classe che rappresenti i contenuti selezionati. Utilizza una classe Parcelable per supportare il salvataggio e il ripristino dell'elemento di elenco selezionato. Utilizza il plug-in kotlin-parcelize per generare il codice.
  2. Crea un ThreePaneScaffoldNavigator con rememberListDetailPaneScaffoldNavigator.

Questo navigatore viene utilizzato per spostarsi tra i riquadri elenco, dettagli e aggiuntivi. Dichiarando un tipo generico, il navigatore tiene traccia anche dello stato dello scaffold (ovvero quale MyItem viene visualizzato). Poiché questo tipo è pacchettizzabile, lo stato può essere salvato e ripristinato dal navigatore per gestire automaticamente le modifiche alla configurazione.

  1. Passa il navigatore al composable NavigableListDetailPaneScaffold.

  2. Fornisci l'implementazione del riquadro dell'elenco al NavigableListDetailPaneScaffold. Utilizza AnimatedPane per applicare le animazioni predefinite del riquadro durante la navigazione. Poi utilizza ThreePaneScaffoldNavigator per andare al riquadro dei dettagli, ListDetailPaneScaffoldRole.Detail, e visualizzare l'elemento passato.

  3. Includi l'implementazione del riquadro dei dettagli in NavigableListDetailPaneScaffold.

Al termine della navigazione, currentDestination contiene il riquadro a cui è stata indirizzata la tua 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.

  1. (Facoltativo) Modifica defaultBackBehavior in NavigableListDetailPaneScaffold. Per impostazione predefinita, NavigableListDetailPaneScaffold utilizza PopUntilScaffoldValueChange per defaultBackBehavior.

Se la tua app richiede un pattern di navigazione indietro diverso, puoi ignorare questo comportamento specificando un'altra opzione BackNavigationBehavior.

BackNavigationBehavior opzioni

La sezione seguente utilizza l'esempio di un'app di posta elettronica con un elenco di email in un riquadro e una visualizzazione dettagliata nell'altro.

Questo comportamento si concentra sulle modifiche alla struttura generale del layout. In una configurazione a più riquadri, la modifica dei contenuti dell'email nel riquadro dei dettagli non altera la struttura del layout sottostante. Pertanto, il pulsante Indietro potrebbe chiudere l'app o il grafico di navigazione corrente perché non è possibile ripristinare alcuna modifica del layout nel contesto attuale. In un layout a un solo riquadro, premendo Indietro si scorreranno le modifiche ai contenuti all'interno della visualizzazione dettagli e si tornerà alla visualizzazione elenco, in quanto ciò rappresenta una chiara modifica del layout.

Considera i seguenti esempi:

  • Multipanel: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 dell'elenco e dei dettagli rimangono visibili. Se premi Indietro, potresti uscire dall'app o dal flusso di navigazione corrente.
  • Singola finestra:visualizzi l'elemento 1, poi l'elemento 2. Se premi Indietro, tornerai direttamente al riquadro dell'elenco delle email.

Utilizza questa opzione quando vuoi che gli utenti percepiscano transizioni di layout distinte a ogni azione Indietro.

Modifica del valore di navigazione.
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 i seguenti esempi:

  • Multivetrina:visualizzi l'elemento 1 nel riquadro dei dettagli, poi fai clic sull'elemento 2 nell'elenco. Il riquadro dei dettagli viene aggiornato. Se premi Indietro, il riquadro dei dettagli tornerà all'elemento 1.
  • Singolo riquadro:si verifica lo stesso ripristino dei contenuti.

Utilizza questo valore quando l'utente si aspetta di tornare ai contenuti visualizzati in precedenza con l'azione Indietro.

la transizione tra due riquadri dei dettagli
PopUntilCurrentDestinationChange

Questo comportamento fa uscire dallo stack precedente fino a quando non cambia la destinazione di navigazione corrente. Questo vale sia per i layout a un solo riquadro sia per quelli a più riquadri.

Considera i seguenti esempi:

Indipendentemente dal layout a un solo riquadro o a più riquadri, se premi Indietro lo stato attivo si sposta sempre dall'elemento di navigazione evidenziato alla destinazione precedente. Nella nostra app di posta, ciò significa che l'indicazione visiva del riquadro selezionato cambierà.

Utilizza questa opzione quando mantenere un'indicazione visiva chiara della navigazione corrente è fondamentale per l'esperienza utente.

navigazione tra i riquadri dei dettagli e dell&#39;elenco
PopLatest

Questa opzione rimuove solo la destinazione più recente dallo stack precedente. Utilizza questa opzione per la navigazione indietro senza saltare gli stati intermedi.

Dopo aver implementato questi passaggi, il codice dovrebbe essere simile al seguente:

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)
            }
        }
    },
)