Riquadro di navigazione a scomparsa

Il componente riquadro di navigazione è un menu a scorrimento che consente agli utenti di navigare nelle varie sezioni dell'app. Gli utenti possono attivarlo scorrendo dal lato o toccando un'icona del menu.

Prendi in considerazione questi tre casi d'uso per l'implementazione di un riquadro di navigazione:

  • Organizzazione dei contenuti:consente agli utenti di passare da una categoria all'altra, ad esempio nelle app di notizie o di blogging.
  • Gestione dell'account:fornisce link rapidi alle impostazioni dell'account e alle sezioni del profilo nelle app con account utente.
  • Rilevamento delle funzionalità: organizza più funzionalità e impostazioni in un unico menu per facilitare la scoperta e l'accesso degli utenti in app complesse.

In Material Design esistono due tipi di riquadri di navigazione:

  • Standard:condividi lo spazio all'interno di uno schermo con altri contenuti.
  • Modale:viene visualizzato sopra gli altri contenuti all'interno di una schermata.
Esempio di un riquadro di navigazione Material Design 3 in modalità chiara e scura.
Figura 1. Esempio di un riquadro di navigazione.

Esempio

Puoi utilizzare il composable ModalNavigationDrawer per implementare un menu di navigazione.

Utilizza lo slot drawerContent per fornire un ModalDrawerSheet e fornisci i contenuti del riquadro, come nell'esempio seguente:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                label = { Text(text = "Drawer Item") },
                selected = false,
                onClick = { /*TODO*/ }
            )
            // ...other drawer items
        }
    }
) {
    // Screen content
}

ModalNavigationDrawer accetta una serie di parametri aggiuntivi per il riquadro. Ad esempio, puoi attivare o disattivare la risposta del riquadro ai trascinamenti con il parametro gesturesEnabled, come nell'esempio seguente:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            // Drawer contents
        }
    },
    gesturesEnabled = false
) {
    // Screen content
}

Comportamento del controllo

Per controllare l'apertura e la chiusura del riquadro a scomparsa, utilizza DrawerState. Devi trasferire un DrawerState a ModalNavigationDrawer utilizzando il parametro drawerState.

DrawerState fornisce l'accesso alle funzioni open e close, nonché alle proprietà relative allo stato attuale del riquadro. Queste funzioni di sospensione richiedono un CoroutineScope, che puoi istanziare utilizzando rememberCoroutineScope. Puoi anche chiamare le funzioni di sospensione in risposta agli eventi dell'interfaccia utente.

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet { /* Drawer content */ }
    },
) {
    Scaffold(
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text("Show drawer") },
                icon = { Icon(Icons.Filled.Add, contentDescription = "") },
                onClick = {
                    scope.launch {
                        drawerState.apply {
                            if (isClosed) open() else close()
                        }
                    }
                }
            )
        }
    ) { contentPadding ->
        // Screen content
    }
}

Creare gruppi all'interno di un riquadro di navigazione

Il seguente snippet mostra come creare un riquadro di navigazione dettagliato, con sezioni e separatori:

@Composable
fun DetailedDrawerExample(
    content: @Composable (PaddingValues) -> Unit
) {
    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    val scope = rememberCoroutineScope()

    ModalNavigationDrawer(
        drawerContent = {
            ModalDrawerSheet {
                Column(
                    modifier = Modifier.padding(horizontal = 16.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    Spacer(Modifier.height(12.dp))
                    Text("Drawer Title", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleLarge)
                    HorizontalDivider()

                    Text("Section 1", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Item 1") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Item 2") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )

                    HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))

                    Text("Section 2", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Settings") },
                        selected = false,
                        icon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                        badge = { Text("20") }, // Placeholder
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Help and feedback") },
                        selected = false,
                        icon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                        onClick = { /* Handle click */ },
                    )
                    Spacer(Modifier.height(12.dp))
                }
            }
        },
        drawerState = drawerState
    ) {
        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text("Navigation Drawer Example") },
                    navigationIcon = {
                        IconButton(onClick = {
                            scope.launch {
                                if (drawerState.isClosed) {
                                    drawerState.open()
                                } else {
                                    drawerState.close()
                                }
                            }
                        }) {
                            Icon(Icons.Default.Menu, contentDescription = "Menu")
                        }
                    }
                )
            }
        ) { innerPadding ->
            content(innerPadding)
        }
    }
}

Punti chiave del codice

  • Compila drawerContent con un Column contenente sezioni, separatori ed elementi di navigazione.
  • ModalDrawerSheet fornisce lo stile Material Design per il riquadro.
  • HorizontalDivider separa le sezioni all'interno del riquadro.
  • ModalNavigationDrawer crea il riquadro.
  • drawerContent definisce i contenuti del riquadro.
  • All'interno di ModalDrawerSheet, un Column dispone gli elementi del riquadro verticalmente.
  • I composable NavigationDrawerItem rappresentano i singoli elementi nel riquadro.
  • Il Scaffold fornisce la struttura di base della schermata, incluso il TopAppBar.
  • Il navigationIcon in TopAppBar controlla lo stato di apertura e chiusura del riquadro a scomparsa.

Risultato

La seguente immagine mostra l'aspetto del riquadro quando viene aperto, con le sezioni e gli elementi visualizzati:

Un riquadro di navigazione dettagliato con due sezioni, ognuna con più elementi ed icone etichettati.
Figura 2. Si è aperto un riquadro di navigazione a scomparsa con due gruppi nidificati.

Risorse aggiuntive