Menu

Menu rozwijane umożliwiają użytkownikom kliknięcie ikony, pola tekstowego lub innego komponentu, a następnie wybranie opcji z listy na tymczasowej powierzchni. Z tego przewodnika dowiesz się, jak tworzyć zarówno podstawowe menu, jak i bardziej złożone menu z separatorami i ikonami.

Wyświetla się menu z 2 opcjami. Ikona z 3 pionowymi kropkami wskazuje, że kliknięcie jej otwiera menu.
Rysunek 1. Podstawowe menu z 2 pozycjami.

Interfejs API

Aby wdrożyć niestandardowe menu, użyj komponentów DropdownMenu, DropdownMenuItem i IconButton. Komponenty DropdownMenu i DropdownMenuItem służą do wyświetlania elementów menu, a IconButton jest aktywatorem wyświetlania lub ukrywania menu.

Najważniejsze parametry komponentu DropdownMenu:

  • expanded: wskazuje, czy menu jest widoczne.
  • onDismissRequest: służy do obsługi zamykania menu.
  • content: treść menu, która może być funkcją kompozycyjną, zwykle zawierająca funkcje kompozycyjne DropdownMenuItem.

Najważniejsze parametry DropdownMenuItem to:

  • text: określa treść wyświetlaną w pozycji menu.
  • onClick: wywołanie zwrotne do obsługi interakcji z elementem w menu.

Tworzenie podstawowego menu

Poniższy fragment kodu pokazuje minimalną implementację 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... */ }
            )
        }
    }
}

Najważniejsze informacje o kodzie

  • Definiuje podstawowy element DropdownMenu zawierający 2 pozycje menu.
  • Parametr expanded określa, czy menu jest rozwinięte czy zwinięte.
  • Parametr onDismissRequest definiuje wywołanie zwrotne, które jest wykonywane, gdy użytkownik zamknie menu.
  • Funkcja kompozycyjna DropdownMenuItem reprezentuje elementy do wyboru w menu.
  • IconButton powoduje rozwinięcie i zwinięcie menu.

Wynik

Menu, które otwiera się po kliknięciu ikony z 3 pionowymi kropkami. W menu wyświetlają się 2 opcje do wyboru: Opcja 1 i Opcja 2.
Rysunek 2. Minimalistyczne menu z tylko 2 opcjami.

Tworzenie dłuższego menu

Jeśli nie można wyświetlić wszystkich elementów menu naraz, domyślnie można przewijać DropdownMenu. Poniższy fragment kodu tworzy dłuższe, przewijane menu:

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

Najważniejsze informacje o kodzie

  • Komponent DropdownMenu można przewijać, gdy łączna wysokość jego zawartości przekracza dostępną przestrzeń. Ten kod tworzy przewijany element DropdownMenu, który wyświetla 100 obiektów zastępczych.
  • Pętla forEach dynamicznie generuje elementy kompozycyjne DropdownMenuItem. Elementy nie są tworzone leniwie, co oznacza, że wszystkie 100 elementów menu jest tworzonych i istnieje w kompozycji.
  • Kliknięcie elementu IconButton powoduje rozwinięcie i zwinięcie elementu DropdownMenu.
  • Funkcja lambda onClick w każdym elemencie DropdownMenuItem pozwala zdefiniować działanie wykonywane, gdy użytkownik wybierze element menu.

Wynik

Poprzedni fragment kodu generuje to przewijane menu:

Menu z wieloma opcjami, które wymaga przewijania, aby wyświetlić wszystkie elementy.
Rysunek 3. Długie menu, które można przewijać.

Tworzenie dłuższego menu z separatorami

Poniższy fragment kodu pokazuje bardziej zaawansowaną implementację menu. W tym fragmencie kodu do elementów menu dodawane są ikony na początku i na końcu, a grupy elementów menu są rozdzielane separatorami.

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

Ten kod definiuje element DropdownMenu w elemencie Box.

Najważniejsze informacje o kodzie

  • Parametry leadingIcon i trailingIcon dodają ikony na początku i na końcu elementu DropdownMenuItem.
  • IconButton powoduje rozwinięcie menu.
  • DropdownMenu zawiera kilka funkcji kompozycyjnych DropdownMenuItem, z których każda reprezentuje działanie do wyboru.
  • Komponenty HorizontalDivider wstawiają poziomą linię, aby oddzielić grupy elementów menu.

Wynik

Powyższy fragment kodu tworzy menu z ikonami i separatorami:

Menu z sekcjami Profil, Ustawienia, Prześlij opinię, Informacje i Pomoc. Każda opcja ma ikonę, np. ikonę osoby w przypadku profilu.
Rysunek 4. Menu podzielone na sekcje z ikonami na początku i na końcu.

Dodatkowe materiały

  • Material Design: menu