Jetpack 撰写弹出菜单

res*_*ser 4 android kotlin android-jetpack-compose

我正在尝试使用 Jetpack compose 重写我的项目 UI。任何想法在android中使用jetpack compose添加弹出菜单? 像这个

我尝试使用 Stack() 布局来实现它,但结果不符合标准。

@Composable
fun LiveDataComponentList(productList: List<Product>) {
    AdapterList(data = productList) { product ->
        Stack() {
            Clickable(onClick = { PopupState.toggleOwner(product) }) {
                Card(...) {...}

            if (PopupState.owner == product) {
                Surface(color = Color.Gray,modifier = Modifier.gravity(Alignment.TopEnd) + Modifier.padding(12.dp)) {
                    Column() {
                        Text("menu 1")
                        Text("menu 2")
                        Text("menu 3")
                        Text("menu 4")
                        Text("menu 5")
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和 PopupState 是

@Model
object PopupState
{
    var owner:Product?=null
    fun toggleOwner(item:Product)
    {
        if(owner==item)
            owner=null
        else
            owner=item
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是

截屏

Gab*_*tti 37

您可以使用DropdownMenu.

就像是:

var expanded by remember { mutableStateOf(false) }

DropdownMenu(
    expanded = expanded,
    onDismissRequest = { expanded = false }
) {
    DropdownMenuItem(
        text = {  Text("Refresh") },
        onClick = { /* Handle refresh! */ }
    )
    DropdownMenuItem(
        text = { Text("Settings") },
        onClick = { /* Handle settings! */ }
    )
    Divider()
    DropdownMenuItem(
        text = { Text("Send Feedback") },
        onClick = { /* Handle send feedback! */ }
    )
}
Run Code Online (Sandbox Code Playgroud)

它与 M3 配合使用。对于 M2,您必须使用:

androidx.compose.material.DropdownMenuItem(
    onClick = { expanded = false }
) {
    Text("All Accounts")
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

关于该职位,如文档中所述:

A 的DropdownMenu行为与 a 类似Popup,并且将使用父布局的位置将其自身定位在屏幕上。通常, aDropdownMenu将被放置在 a 中Box,并且其兄弟姐妹将用作“锚点”

例子:

Box(
    modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.TopStart)
){
    IconButton(onClick = { expanded = true }) {
        Icon(
            Icons.Default.MoreVert,
            contentDescription = "Localized description"
        )
    }
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false }
    ) {
        //...
    }
Run Code Online (Sandbox Code Playgroud)


AnT*_*AnT 6

由于删除了 DropDownPopup,我使用DropDownMenu实现了一个,而不是这样:

弹出菜单:

@Composable
fun PopupMenu(
    menuItems: List<String>,
    onClickCallbacks: List<() -> Unit>,
    showMenu: Boolean,
    onDismiss: () -> Unit,
    toggle: @Composable () -> Unit,
) {
    DropdownMenu(
        toggle = toggle,
        expanded = showMenu,
        onDismissRequest = { onDismiss() },
    ) {
        menuItems.forEachIndexed { index, item ->
            DropdownMenuItem(onClick = {
                onDismiss()
                onClickCallbacks[index]
            }) {
                Text(text = item)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

切换(长按触发 PopupMenu 的东西):

@Preview
@Composable
fun Toggle() {
    var showMenu by remember { mutableStateOf(false) }

    PopupMenu(
        menuItems = listOf("Delete"),
        onClickCallbacks = listOf { println("Deleted") },
        showMenu = showMenu,
        onDismiss = { showMenu = false }) {
        Text(
            modifier = Modifier.clickable(onClick = {}, onLongClick = {
                showMenu = true
            }),
            text = "Long click here",
        )
    }
}
Run Code Online (Sandbox Code Playgroud)