Gaveta de navegação

O componente gaveta de navegação é um menu deslizante que permite aos usuários navegar por várias seções do app. Os usuários podem ativar esse recurso deslizando da lateral ou tocando em um ícone de menu.

Considere estes três casos de uso para implementar um gaveta de navegação:

  • Organização de conteúdo:permita que os usuários alternem entre diferentes categorias, como em apps de notícias ou blogs.
  • Gerenciamento da conta:fornece links rápidos para as configurações da conta e seções do perfil em apps com contas de usuário.
  • Descoberta de recursos:organize vários recursos e configurações em um único menu para facilitar a descoberta e o acesso do usuário em apps complexos.

No Material Design, há dois tipos de gavetas de navegação:

  • Padrão:compartilha espaço em uma tela com outros conteúdos.
  • Modal:aparece sobre outros conteúdos em uma tela.
Exemplo de um gavete de navegação do Material Design 3 nos modos claro e escuro.
Figura 1. Exemplo de uma gaveta de navegação.

Exemplo

Você pode usar o elemento combinável ModalNavigationDrawer para implementar uma gaveta de navegação.

Use o slot drawerContent para fornecer um ModalDrawerSheet e o conteúdo da gaveta, como no exemplo a seguir:

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 aceita vários outros parâmetros de gaveta. Por exemplo, é possível ativar ou desativar a resposta da gaveta às ações de arrastar com o parâmetro gesturesEnabled, como no exemplo a seguir:

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

Comportamento de controle

Para controlar como o gaveteiro abre e fecha, use DrawerState. Você precisa transmitir um DrawerState para ModalNavigationDrawer usando o parâmetro drawerState.

DrawerState fornece acesso às funções open e close, além de propriedades relacionadas ao estado atual da gaveta. Essas funções de suspensão exigem um CoroutineScope, que pode ser instanciado usando rememberCoroutineScope. Você também pode chamar as funções de suspensão em resposta a eventos da interface.

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

Criar grupos em uma gaveta de navegação

O snippet a seguir mostra como criar um gaveta de navegação detalhada, com seções e divisores:

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

Pontos principais sobre o código

  • Preenche o drawerContent com um Column que contém seções, divisores e itens de navegação.
  • O ModalDrawerSheet fornece o estilo do Material Design para a gaveta.
  • O HorizontalDivider separa as seções dentro da gaveta.
  • ModalNavigationDrawer cria a gaveta.
  • drawerContent define o conteúdo da gaveta.
  • Dentro do ModalDrawerSheet, um Column organiza os elementos da gaveta verticalmente.
  • Os elementos combináveis NavigationDrawerItem representam itens individuais no menu suspenso.
  • O Scaffold fornece a estrutura básica da tela, incluindo o TopAppBar.
  • O navigationIcon no TopAppBar controla o estado de abertura e fechamento da gaveta.

Resultado

A imagem a seguir mostra como a gaveta aparece quando aberta, com seções e itens exibidos:

Uma gaveta de navegação detalhada com duas seções, cada uma com vários itens e ícones rotulados.
Figura 2. Uma gaveta de navegação aberta com dois grupos aninhados.

Outros recursos