Меню

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

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

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

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

Основные параметры компонента DropdownMenu:

  • expanded – указывает, видно ли меню.
  • onDismissRequest: используется для закрытия меню.
  • content – составной контент меню, обычно содержащий composable-функции 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. Раскрывающееся меню, разделенное на разделы с ведущими и завершающими значками.

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