Меню

Раскрывающиеся меню позволяют пользователям щёлкнуть по значку, текстовому полю или другому компоненту, а затем выбрать один из вариантов на временной поверхности. В этом руководстве описывается, как создавать как простые, так и более сложные меню с разделителями и значками.

Раскрывающееся меню с двумя пунктами. Значок с тремя вертикальными точками означает, что нажатие на него открывает меню.
Рисунок 1. Простое раскрывающееся меню с двумя пунктами.

API поверхность

Используйте компоненты DropdownMenu , DropdownMenuItem и IconButton для реализации пользовательского раскрывающегося меню. Компоненты DropdownMenu и DropdownMenuItem используются для отображения пунктов меню, а IconButton — это триггер отображения или скрытия раскрывающегося меню.

Ключевые параметры компонента DropdownMenu включают следующее:

  • expanded : указывает, видно ли меню.
  • onDismissRequest : используется для обработки закрытия меню.
  • content : компонуемое содержимое меню, обычно содержащее компонуемые элементы DropdownMenuItem .

Ключевые параметры DropdownMenuItem включают следующее:

  • text : определяет содержимое, отображаемое в пункте меню.
  • onClick : Обратный вызов для обработки взаимодействия с элементом меню.

Создайте простое раскрывающееся меню

В следующем фрагменте показана минимальная реализация 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... */ }
            )
        }
    }
}

Ключевые моменты кода

  • Определяет базовое DropdownMenu , содержащее два пункта меню.
  • Параметр expanded управляет видимостью меню в развернутом или свернутом виде.
  • Параметр onDismissRequest определяет обратный вызов, который выполняется, когда пользователь закрывает меню.
  • Композиционный элемент DropdownMenuItem представляет собой выбираемые элементы в раскрывающемся меню.
  • Кнопка IconButton активирует развертывание и свертывание меню.

Результат

Выпадающее меню, вызываемое значком с тремя вертикальными точками. В меню представлены два варианта выбора: «Вариант 1» и «Вариант 2».
Рисунок 2. Минимальное раскрывающееся меню, содержащее всего два пункта.

Создайте более длинное раскрывающееся меню

DropdownMenu по умолчанию прокручивается, если все пункты меню не могут быть отображены одновременно. Следующий фрагмент кода создаёт более длинное прокручиваемое раскрывающееся меню:

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

Ключевые моменты кода

  • DropdownMenu можно прокручивать, когда общая высота его содержимого превышает доступное пространство. Этот код создаёт прокручиваемое DropdownMenu , отображающее 100 элементов-заполнителей.
  • Цикл forEach динамически генерирует элементы DropdownMenuItem , которые можно компоновать. Элементы не создаются лениво, то есть все 100 раскрывающихся элементов создаются и присутствуют в композиции.
  • При нажатии на значок IconButton происходит развертывание и свертывание DropdownMenu .
  • Лямбда-функция onClick в каждом DropdownMenuItem позволяет определить действие, выполняемое при выборе пользователем пункта меню.

Результат

Приведенный выше фрагмент кода создает следующее прокручиваемое меню:

Выпадающее меню с множеством опций, требующее прокрутки для просмотра всех пунктов.
Рисунок 3. Длинное прокручиваемое раскрывающееся меню.

Создайте более длинное раскрывающееся меню с разделителями

В следующем фрагменте кода показана более продвинутая реализация раскрывающегося меню. В этом фрагменте к пунктам меню добавляются начальные и конечные значки, а также разделители, разделяющие группы пунктов меню.

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

Этот код определяет DropdownMenu внутри Box .

Ключевые моменты кода

  • Параметры leadingIcon и trailingIcon добавляют значки в начало и конец DropdownMenuItem .
  • Кнопка IconButton активирует расширение меню.
  • DropdownMenu содержит несколько составных элементов DropdownMenuItem , каждый из которых представляет собой выбираемое действие.
  • Компоновочные элементы HorizontalDivider вставляют горизонтальную линию для разделения групп пунктов меню.

Результат

Предыдущий фрагмент создает раскрывающееся меню со значками и разделителями:

Раскрывающееся меню с разделами «Профиль», «Настройки», «Отправить отзыв», «О программе» и «Справка». Каждый пункт имеет значок, например, значок с изображением человечка для профиля.
Рисунок 4. Раскрывающееся меню, разделенное на секции с начальными и конечными значками.

Дополнительные ресурсы