Panneau de navigation

Le composant panneau de navigation est un menu coulissant qui permet aux utilisateurs d'accéder à différentes sections de votre application. Les utilisateurs peuvent l'activer en balayant l'écran depuis le côté ou en appuyant sur une icône de menu.

Voici trois cas d'utilisation d'un panneau de navigation :

  • Organisation du contenu : permettez aux utilisateurs de passer d'une catégorie à l'autre, par exemple dans les applications d'actualités ou de blogs.
  • Gestion de compte : fournissez des liens rapides vers les paramètres du compte et les sections du profil dans les applications avec des comptes utilisateur.
  • Découverte de fonctionnalités : organisez plusieurs fonctionnalités et paramètres dans un seul menu pour faciliter la découverte et l'accès des utilisateurs dans les applications complexes.

Dans Material Design, il existe deux types de panneaux de navigation :

  • Standard : partage l'espace d'un écran avec d'autres contenus.
  • Modal : s'affiche au-dessus des autres contenus d'un écran.
Exemple de panneau de navigation Material Design 3 en mode clair et sombre.
Figure 1. Exemple de panneau de navigation

Exemple

Vous pouvez utiliser le composable ModalNavigationDrawer pour implémenter un panneau de navigation.

Utilisez l'emplacement drawerContent pour fournir un ModalDrawerSheet et le contenu du panneau, comme dans l'exemple suivant :

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 accepte un certain nombre de paramètres de panneau supplémentaires. Par exemple, vous pouvez activer ou désactiver la réaction du panneau aux gestes de type glisser à l'aide du paramètre gesturesEnabled, comme dans l'exemple suivant :

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

Contrôler le comportement

Pour contrôler l'ouverture et la fermeture du panneau, utilisez DrawerState. Vous devez transmettre un DrawerState à ModalNavigationDrawer à l'aide du paramètre drawerState.

DrawerState fournit un accès aux fonctions open et close, ainsi qu'aux propriétés liées à l'état actuel du panneau. Ces fonctions de suspension nécessitent un CoroutineScope, que vous pouvez instancier à l'aide de rememberCoroutineScope. Vous pouvez également appeler les fonctions de suspension en réponse à des événements d'UI.

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

Créer des groupes dans un panneau de navigation

L'extrait de code suivant montre comment créer un panneau de navigation détaillé, avec des sections et des séparateurs :

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

Points clés concernant le code

  • Remplit le drawerContent avec un Column contenant des sections, des séparateurs et des éléments de navigation.
  • ModalDrawerSheet fournit un style Material Design pour le panneau.
  • HorizontalDivider sépare les sections dans le panneau.
  • ModalNavigationDrawer crée le panneau.
  • drawerContent définit le contenu du panneau.
  • Dans le ModalDrawerSheet, un Column organise les éléments du panneau latéral verticalement.
  • Les composables NavigationDrawerItem représentent des éléments individuels dans le panneau.
  • Scaffold fournit la structure de base de l'écran, y compris TopAppBar.
  • navigationIcon dans TopAppBar contrôle l'état d'ouverture et de fermeture du panneau.

Résultat

L'image suivante montre comment le panneau s'affiche lorsqu'il est ouvert, avec les sections et les éléments affichés :

Panneau de navigation détaillé avec deux sections, chacune comportant plusieurs éléments et icônes libellés.
Figure 2. Panneau de navigation ouvert avec deux groupes imbriqués.

Ressources supplémentaires