Gaveta de navegação

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

Considere estes três casos de uso para implementar uma 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 de contas:forneça links rápidos para as configurações da conta e as 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 outro conteúdo.
  • Modal:aparece sobre outros conteúdos em uma tela.
Figura 1. Exemplo de 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 fornecer o conteúdo da gaveta, como no exemplo abaixo:

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
}

Controlar o comportamento

Para controlar como a gaveta é aberta e fechada, use DrawerState. É necessário 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. Também é possível 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 uma 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.
  • ModalDrawerSheet fornece o estilo do Material Design para a gaveta.
  • HorizontalDivider separa as seções dentro da gaveta.
  • ModalNavigationDrawer cria a gaveta.
  • drawerContent define o conteúdo da gaveta.
  • Dentro da ModalDrawerSheet, um Column organiza os elementos da gaveta verticalmente.
  • Os elementos combináveis NavigationDrawerItem representam itens individuais na gaveta.
  • 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