android compose DropdownMenu 菜单 使用
DropdownMenu 组件的关键参数包括以下内容:
expanded:表示菜单是否可见。onDismissRequest:用于处理菜单关闭。content:菜单的可组合内容,通常包含DropdownMenuItem可组合项。
DropdownMenuItem 的关键参数包括以下内容:
text:定义菜单项中显示的内容。onClick:用于处理与菜单中项的交互的回调。
leadingIcon和trailingIcon参数会将图标添加到DropdownMenuItem的开头和结尾。

package com.wn.androidcomposedemo1.basegoogle
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Send
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.Send
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import com.wn.androidcomposedemo1.ui.theme.AndroidComposeDemo1Theme
import kotlin.math.exp
/**
* Author : wn
* Email : maoning20080808@163.com
* Date : 2026/6/26 21:06
* Description : 下拉菜单
*/
class DropdownMenuActivity : ComponentActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AndroidComposeDemo1Theme() {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
DropdownMenuExample()
}
}
}
}
@Preview
@Composable
fun DropdownMenuExample(){
Column() {
Spacer(Modifier.height(20.dp))
MinimalDropdownMenu()
Spacer(Modifier.height(20.dp))
DropdownMenuWithDetails()
}
}
//分割线菜单
@Preview
@Composable
fun DropdownMenuWithDetails(){
var expanded by remember { mutableStateOf(false) }
Box(modifier = Modifier.fillMaxWidth().padding(16.dp)){
Row() {
Text("分割线菜单")
IconButton(
onClick = {
expanded = !expanded
}
) {
Icon(Icons.Default.MoreVert, contentDescription = "更多选项")
}
}
DropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
DropdownMenuItem(
text = {Text("个人信息")},
leadingIcon = {
Icon(Icons.Outlined.Person, contentDescription = null)
},
onClick = {
Log.d("AAA", "点击个人信息")
}
)
DropdownMenuItem(
text = {Text("设置")},
leadingIcon = {Icon(Icons.Outlined.Settings, contentDescription = null)},
onClick = {
Log.d("AAA", "点击设置")
}
)
HorizontalDivider()
DropdownMenuItem(
text = {Text("反馈")},
leadingIcon = {Icon(Icons.Outlined.Add, contentDescription = null)},
trailingIcon = {Icon(Icons.AutoMirrored.Outlined.Send, contentDescription = null)},
onClick = {
Log.d("AAA", "点击反馈")
}
)
HorizontalDivider()
DropdownMenuItem(
text = {Text("关于")},
leadingIcon = {Icon(Icons.Outlined.Info, contentDescription = null)},
onClick = {
Log.d("AAA", "点击关于")
}
)
DropdownMenuItem(
text = {Text("帮助")},
leadingIcon = {Icon(Icons.Outlined.Home, contentDescription = null)},
trailingIcon = {Icon(Icons.Outlined.Info, contentDescription = null)},
onClick = {
Log.d("AAA", "点击帮助")
}
)
}
}
}
//弹出菜单
@Preview
@Composable
fun MinimalDropdownMenu(){
var expanded by remember { mutableStateOf(false) }
// Box 在根布局中的位置
var boxPosition by remember { mutableStateOf(Offset.Zero) }
//保存IconButton的屏幕坐标
var buttonPosition by remember { mutableStateOf(Offset.Zero) }
//保存IconButton的尺寸
var buttonSize by remember { mutableStateOf(Offset.Zero) }
val density = LocalDensity.current
Box(
modifier = Modifier.padding(16.dp)
.onGloballyPositioned{ coordinates ->
boxPosition = coordinates.positionInRoot()
}
){
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text("请选择菜单")
IconButton(
modifier = Modifier.onGloballyPositioned { coordinates ->
//使用 positionInParent 获取相对于 Box 的坐标
buttonPosition = coordinates.positionInRoot()
buttonSize = Offset(
coordinates.size.width.toFloat(),
coordinates.size.height.toFloat()
)
},
onClick = {
expanded = !expanded
}) {
Icon(Icons.Default.MoreVert, contentDescription = "更多选项")
}
}
DropdownMenu(expanded = expanded,
onDismissRequest = {
expanded = false
},
offset = with(density){
//计算按钮相对于Box的坐标
val relativeX = buttonPosition.x - boxPosition.x
val relativeY = buttonPosition.y - boxPosition.y + buttonSize.y
DpOffset(
x = relativeX.toDp(),
y = relativeY.toDp()
)
}
) {
DropdownMenuItem(
text = { Text("选项1") },
onClick = {
Log.d("AAA", "点击选项1")
}
)
DropdownMenuItem(
text = {Text("选项1")},
onClick = {
Log.d("AAA", "点击选项2")
}
)
DropdownMenuItem(
text = {Text("选项3")},
onClick = {
Log.d("AAA", "点击选项3")
}
)
}
}
}
}