Menús

Los menús desplegables permiten que los usuarios hagan clic en un ícono, un campo de texto o algún otro componente y, luego, seleccionen una opción de una lista en una superficie temporal. En esta guía, se describe cómo crear menús básicos y más complejos con divisores y íconos.

Un menú desplegable con dos opciones. Un ícono con tres puntos verticales indica que, si haces clic en él, se abrirá el menú.
Figura 1: Un menú desplegable básico con dos elementos en la lista.

Plataforma de la API

Usa los componentes DropdownMenu, DropdownMenuItem y IconButton para implementar un menú desplegable personalizado. Los componentes DropdownMenu y DropdownMenuItem se usan para mostrar los elementos del menú, mientras que IconButton es el activador para mostrar o ocultar el menú desplegable.

Los parámetros clave del componente DropdownMenu incluyen los siguientes:

  • expanded: Indica si el menú es visible.
  • onDismissRequest: Se usa para controlar el descarte del menú.
  • content: Es el contenido componible del menú, que suele contener elementos componibles DropdownMenuItem.

Los parámetros clave de DropdownMenuItem incluyen los siguientes:

  • text: Define el contenido que se muestra en el elemento de menú.
  • onClick: Es la devolución de llamada para controlar la interacción con el elemento del menú.

Cómo crear un menú desplegable básico

En el siguiente fragmento, se muestra una implementación 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... */ }
            )
        }
    }
}

Puntos clave sobre el código

  • Define un DropdownMenu básico que contiene dos elementos de menú.
  • El parámetro expanded controla la visibilidad del menú como expandido o collapsed.
  • El parámetro onDismissRequest define una devolución de llamada que se ejecuta cuando el usuario cierra el menú.
  • El elemento componible DropdownMenuItem representa los elementos seleccionables en el menú desplegable.
  • Un IconButton activa la expansión y el colapso del menú.

Resultado

Un menú desplegable activado por un ícono con tres puntos verticales. El menú muestra dos opciones para elegir: Opción 1 y Opción 2.
Figura 2: Un menú desplegable minimalista con solo dos opciones.

Cómo crear un menú desplegable más largo

DropdownMenu se puede desplazar de forma predeterminada si no se pueden mostrar todos los elementos del menú a la vez. El siguiente fragmento crea un menú desplegable más largo y desplazable:

@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... */ }
                )
            }
        }
    }
}

Puntos clave sobre el código

  • El DropdownMenu se puede desplazar cuando la altura total de su contenido supera el espacio disponible. Este código crea un DropdownMenu desplazable que muestra 100 elementos de marcador de posición.
  • El bucle forEach genera elementos DropdownMenuItem componibles de forma dinámica. Los elementos no se crean de forma diferida, lo que significa que los 100 elementos del menú desplegable se crean y existen en la composición.
  • El IconButton activa la expansión y contracción de DropdownMenu cuando se hace clic en él.
  • La lambda onClick dentro de cada DropdownMenuItem te permite definir la acción que se realiza cuando el usuario selecciona un elemento de menú.

Resultado

El fragmento de código anterior produce el siguiente menú desplazable:

Un menú desplegable con muchas opciones que requiere desplazamiento para ver todos los
  elementos.
Figura 3: Un menú desplegable largo y desplazable.

Crea un menú desplegable más largo con divisores

En el siguiente fragmento, se muestra una implementación más avanzada de un menú desplegable. En este fragmento, se agregan íconos iniciales y finales a los elementos de menú, y los divisores separan grupos de elementos de menú.

@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... */ }
            )
        }
    }
}

Este código define un DropdownMenu dentro de un Box.

Puntos clave sobre el código

  • Los parámetros leadingIcon y trailingIcon agregan íconos al principio y al final de un DropdownMenuItem.
  • Un IconButton activa la expansión del menú.
  • El DropdownMenu contiene varios elementos componibles DropdownMenuItem, cada uno de los cuales representa una acción que se puede seleccionar.
  • Los elementos componibles HorizontalDivider insertan una línea horizontal para separar grupos de elementos de menú.

Resultado

El fragmento anterior produce un menú desplegable con íconos y divisores:

Un menú desplegable con secciones para Perfil, Configuración, Enviar comentarios, Acerca de y
Figura 4: Un menú desplegable dividido en secciones con íconos iniciales y finales.

Recursos adicionales