借助下拉菜单,用户可以点击图标、文本字段或其他组件,然后在临时界面上从选项列表中进行选择。本指南介绍了如何创建基本菜单,以及如何创建包含分隔线和图标的更复杂的菜单。
API Surface
使用 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会触发菜单的展开和收起。
结果
创建较长的下拉菜单
如果无法一次显示所有菜单项,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的展开和收起。 - 借助每个
DropdownMenuItem中的onClicklambda,您可以定义在用户选择菜单项时执行的操作。
结果
上述代码段会生成以下可滚动菜单:
创建包含分隔线的较长下拉菜单
以下代码段展示了下拉菜单的更高级实现。 在此代码段中,菜单项中添加了前导和尾随图标,并且分隔线将菜单项组分开。
@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。
代码要点
leadingIcon和trailingIcon参数会将图标添加到DropdownMenuItem的开头和结尾。IconButton会触发菜单的展开。DropdownMenu包含多个DropdownMenuItem可组合项,每个 都表示一个可选择的操作。HorizontalDivider可组合项会插入一条水平线,以将菜单项组分开。
结果
上述代码段会生成一个包含图标和分隔线的下拉菜单:
其他资源
- Material Design:菜单