菜单

通过下拉菜单,用户可以点击图标、文本字段或其他组件,然后从临时界面上的选项列表中进行选择。本指南介绍了如何创建基本菜单以及包含分隔符和图标的更复杂的菜单。

显示两个选项的下拉菜单。带有三个垂直点的图标表示点击该图标即可打开菜单。
图 1. 一个列出了两个项的基本下拉菜单。

API Surface

使用 DropdownMenuDropdownMenuItemIconButton 组件实现自定义下拉菜单。DropdownMenuDropdownMenuItem 组件用于显示菜单项,而 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 会可滚动。此代码会创建一个可滚动的 DropdownMenu,用于显示 100 个占位符项。
  • forEach 循环会动态生成 DropdownMenuItem 可组合项。这些项不会延迟创建,这意味着系统会创建所有 100 个下拉菜单项,并将其放入组合中。
  • 点击 IconButton 会触发 DropdownMenu 的展开和收起。
  • 通过每个 DropdownMenuItem 中的 onClick lambda,您可以定义用户选择菜单项时执行的操作。

结果

上述代码段会生成以下可滚动菜单:

包含许多选项的下拉菜单,需要滚动才能查看所有项。
图 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... */ }
            )
        }
    }
}

此代码在 Box 中定义了 DropdownMenu

代码要点

  • leadingIcontrailingIcon 参数会向 DropdownMenuItem 的开头和结尾添加图标。
  • IconButton 会触发菜单展开。
  • DropdownMenu 包含多个 DropdownMenuItem 可组合项,每个可组合项代表一项可选择的操作。
  • HorizontalDivider 可组合项会插入水平线来分隔菜单项组。

结果

上述代码段会生成包含图标和分隔符的下拉菜单:

一个下拉菜单,其中包含“个人资料”“设置”“发送反馈”“关于”和
图 4. 一个分为多个部分的下拉菜单,其中包含前置和后置图标。

其他资源