Search code examples
androidkotlinandroid-jetpack-composeandroid-compose-dropdownmenu

Jetpack compose popup menu


I am trying to rewrite my project UI using Jetpack compose. Any idea to add popup menu using jetpack compose in android?. like this one below.

like this one

I tried to implement it using Stack() layout but the results are not up to the mark.

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

and PopupState is

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

result is

screenshot


Solution

  • You can use the DropdownMenu.

    Something like:

    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! */ }
        )
    }
    

    It works with M3. With M2 you have to use:

    androidx.compose.material.DropdownMenuItem(
        onClick = { expanded = false }
    ) {
        Text("All Accounts")
    }
    

    enter image description here

    About the position, as explained in the documentation:

    A DropdownMenu behaves similarly to a Popup, and will use the position of the parent layout to position itself on screen. Commonly a DropdownMenu will be placed in a Box with a sibling that will be used as the 'anchor'.

    Example:

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