Menus

Os menus suspensos permitem que os usuários cliquem em um ícone, campo de texto ou outro componente e selecionem uma opção em uma lista em uma superfície temporária. Este guia descreve como criar menus básicos e mais complexos com divisores e ícones.

Um menu suspenso com duas opções. Um ícone com três pontos verticais indica que clicar nele abre o menu.
Figura 1. Um menu suspenso básico com dois itens listados.

Superfície da API

Use DropdownMenu, DropdownMenuItem e os componentes IconButton para implementar um menu suspenso personalizado. Os componentes DropdownMenu e DropdownMenuItem são usados para mostrar os itens do menu, enquanto o IconButton é o gatilho para mostrar ou ocultar o menu suspenso.

Os principais parâmetros do componente DropdownMenu incluem:

  • expanded: indica se o menu está visível.
  • onDismissRequest: usado para processar a dispensa do menu.
  • content: o conteúdo combinável do menu, geralmente contendo elementos combináveis DropdownMenuItem.

Os principais parâmetros para DropdownMenuItem incluem:

  • text: define o conteúdo mostrado no item de menu.
  • onClick: callback para processar a interação com o item no menu.

Criar um menu suspenso básico

O snippet a seguir demonstra uma implementação mínima de DropdownMenu:

@Composable
fun MinimalDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }
    Box(
        modifier = Modifier
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            DropdownMenuItem(
                text = { Text("Option 1") },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Option 2") },
                onClick = { /* Do something... */ }
            )
        }
    }
}

Pontos principais sobre o código

  • Define um DropdownMenu básico que contém dois itens de menu.
  • O parâmetro expanded controla a visibilidade do menu como expandido ou recolhido.
  • O parâmetro onDismissRequest define um callback que é executado quando o usuário fecha o menu.
  • O elemento combinável DropdownMenuItem representa itens selecionáveis no menu suspenso.
  • Um IconButton aciona a abertura e o fechamento do menu.

Resultado

Um menu suspenso acionado por um ícone com três pontos verticais. O menu mostra duas opções selecionáveis: "Opção 1" e "Opção 2".
Figura 2. Um menu suspenso mínimo com apenas duas opções.

Criar um menu suspenso mais longo

DropdownMenu pode ser rolado por padrão se todos os itens do menu não puderem ser exibidos de uma só vez. O snippet a seguir cria um menu suspenso mais longo e rolável:

@Composable
fun LongBasicDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }
    // Placeholder list of 100 strings for demonstration
    val menuItemData = List(100) { "Option ${it + 1}" }

    Box(
        modifier = Modifier
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            menuItemData.forEach { option ->
                DropdownMenuItem(
                    text = { Text(option) },
                    onClick = { /* Do something... */ }
                )
            }
        }
    }
}

Pontos principais sobre o código

  • O DropdownMenu pode ser rolado quando a altura total do conteúdo excede o espaço disponível. Esse código cria um DropdownMenu rolável que mostra 100 itens de marcador de posição.
  • O loop forEach gera dinamicamente elementos combináveis DropdownMenuItem. Os itens não são criados de forma lenta, o que significa que todos os 100 itens do menu suspenso são criados e existem na composição.
  • O IconButton aciona a expansão e o fechamento do DropdownMenu quando clicado.
  • A lambda onClick em cada DropdownMenuItem permite definir a ação realizada quando o usuário seleciona um item de menu.

Resultado

O snippet de código anterior produz o seguinte menu rolável:

Um menu suspenso com muitas opções, exigindo rolagem para ver todos os
  itens.
Figura 3. Um menu suspenso longo e rolável.

Criar um menu suspenso mais longo com divisores

O snippet a seguir mostra uma implementação mais avançada de um menu suspenso. Neste snippet, ícones iniciais e finais são adicionados a itens de menu, e divisores separam grupos de itens de menu.

@Composable
fun DropdownMenuWithDetails() {
    var expanded by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            // First section
            DropdownMenuItem(
                text = { Text("Profile") },
                leadingIcon = { Icon(Icons.Outlined.Person, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Settings") },
                leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

            // Second section
            DropdownMenuItem(
                text = { Text("Send Feedback") },
                leadingIcon = { Icon(Icons.Outlined.Feedback, contentDescription = null) },
                trailingIcon = { Icon(Icons.AutoMirrored.Outlined.Send, contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

            // Third section
            DropdownMenuItem(
                text = { Text("About") },
                leadingIcon = { Icon(Icons.Outlined.Info, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Help") },
                leadingIcon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                trailingIcon = { Icon(Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
        }
    }
}

Esse código define um DropdownMenu em um Box.

Pontos principais sobre o código

  • Os parâmetros leadingIcon e trailingIcon adicionam ícones ao início e ao fim de um DropdownMenuItem.
  • Um IconButton aciona a expansão do menu.
  • O DropdownMenu contém vários elementos combináveis DropdownMenuItem, cada um representando uma ação selecionável.
  • Os elementos combináveis HorizontalDivider inserem uma linha horizontal para separar grupos de itens de menu.

Resultado

O snippet anterior produz um menu suspenso com ícones e divisores:

Um menu suspenso com seções para "Perfil", "Configurações", "Enviar feedback", "Sobre" e "Ajuda". Cada opção tem um ícone, como uma pessoa para "Perfil".
Figura 4. Um menu suspenso dividido em seções com ícones à esquerda e à direita.

Outros recursos

  • Material Design: Menus (link em inglês)