Меню

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

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

API surface

Чтобы создать собственное раскрывающееся меню, используйте компоненты 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(painter = rememberVectorPainter(AppIcons.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 определяет обратный вызов, который выполняется, когда пользователь закрывает меню.
  • Composable-функция 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(painter = rememberVectorPainter(AppIcons.MoreVert), contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            menuItemData.forEach { option ->
                DropdownMenuItem(
                    text = { Text(option) },
                    onClick = { /* Do something... */ }
                )
            }
        }
    }
}

Важные сведения о коде

  • Если общая высота контента превышает доступное пространство, DropdownMenu можно прокручивать. Этот код создает прокручиваемый список DropdownMenu, в котором отображается 100 элементов-плейсхолдеров.
  • Цикл forEach динамически генерирует composable-функции 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(painter = rememberVectorPainter(AppIcons.MoreVert), contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            // First section
            DropdownMenuItem(
                text = { Text("Profile") },
                leadingIcon = { Icon(painter = rememberVectorPainter(AppIcons.Person), contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Settings") },
                leadingIcon = { Icon(painter = rememberVectorPainter(AppIcons.Settings), contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

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

            HorizontalDivider()

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

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

Важные сведения о коде

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

Результат

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

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

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