Jetpack组成弹出菜单

时间:2020-05-06 08:37:11

标签: android kotlin android-jetpack-compose

我正在尝试使用Jetpack compose重写我的项目UI。有什么想法可以在Android中使用jetpack来添加弹出菜单吗? like this one

我尝试使用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")
                    }
                }
            }
        }
    }
}

而PopupState是

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

结果是

screenshot

3 个答案:

答案 0 :(得分: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)
            }
        }
    }
}

切换(长按触发弹出菜单的东西):

@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",
        )
    }
}

答案 1 :(得分:3)

经过研究,我找到了解决方案,关键组件是 DropdownPopup

@Composable
fun LiveDataComponentList(productList: List<Product>) {
    AdapterList(data = productList) { product ->


        Clickable(onClick = { PopupState.toggleOwner(product) }) {
            Card(...) {...}
        }
        if (PopupState.owner == product) {
            DropdownPopup(dropDownAlignment = DropDownAlignment.End)
            {

                Surface(
                    shape = RoundedCornerShape(4.dp),
                    elevation = 16.dp,
                    color = Color.White,
                    modifier = Modifier.gravity(Alignment.End)+ Modifier.padding(end = 10.dp)
                )
                {
                    Column(modifier = Modifier.padding(10.dp)) {

                        MenuItem(text ="Edit", onClick = {})
                        MenuItem(text = "Delete", onClick = {})
                        MenuItem(text = "Details", onClick = {})


                    }
                }
            }
        }


    }
}

@Composable
fun MenuItem(text: String, onClick: () -> Unit) {
    Clickable(onClick = onClick, modifier = Modifier.padding(6.dp)) {
        Text(text = text, style = MaterialTheme.typography.subtitle1)

    }
}

此解决方案与撰写版本 dev10

一起使用时效果很好

答案 2 :(得分:3)

通过 1.0.0(使用 1.0.0-beta08 测试),您可以使用 DropdownMenu
类似的东西:

var expanded by remember { mutableStateOf(false) }

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

enter image description here