Skip to content

Jetpack compose dropdown

  • by
Jetpack compose dropdown

1. Overview

In this article, we will learn about the Jetpack compose dropdown. A dropdown menu is a compact way of displaying multiple choices. You can display a dropdown menu upon interaction with a UI element (such as an icon or button) or when users perform a specific action.

2. Jetpack compose DropDown

DropdownMenu uses the position of the parent layout to position itself on the screen. Usually, we place the DropdownMenu in a Box with a sibling that will be used as the ‘anchor’.

Since DropdownMenu appears on top of other content, it will not take up any space in the layout.

You can use the following as content of a DropdownMenu:

2.1. Jetpack compose dropdown example

For example, the following showDropDown function has a Box parent layout which contains an IconButton and DropdownMenu. Here, the IconButton is the anchor element for the DropdownMenu position.

  1. DropdownMenuItem – matches the material design specification
  2. Custom content
@Composable
fun showDropDown() {

    var expanded by remember { mutableStateOf(false) }

    val context = LocalContext.current
    Box(modifier = Modifier
        .fillMaxSize()
        .wrapContentSize(Alignment.TopEnd)) {
        IconButton(onClick = { expanded = true }) {
            Icon(Icons.Default.MoreVert, contentDescription = "Settings")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            DropdownMenuItem(onClick = {
                Toast.makeText(context,"Add",Toast.LENGTH_SHORT).show()
            }) {
                Text("Add")
            }
            DropdownMenuItem(onClick = {
                Toast.makeText(context,"Remove",Toast.LENGTH_SHORT).show()
            }) {
                Text("Remove")
            }
            Divider()
            DropdownMenuItem(onClick = {
                Toast.makeText(context,"Clear",Toast.LENGTH_SHORT).show()
            }) {
                Text("Clear")
            }
        }
    }
}
Jetpack compose dropdown

As you can see, the DropdownMenu position depends on the anchor element.

The DropdownMenu uses the DropdownMenuItem as content elements. On click of each DropdownMenuItem would show a Toast.

We are storing the DropdownMenu state that is expanded or collapsed in the memory by using the mutable state variable.

onDismissRequest will be called when the menu should close.

For example, when there is a tap outside the menu, or when the back key is pressed.

Here, we are also updating the state variable to remember the closed state.

The content is placed inside a scrollable Column, so using a LazyColumn as the root layout inside content is unsupported.

For example, the following DropdownMenuItem (the content of the drop-down) uses the LazyColumn as the root layout.

This is not supported and throws a runtime exception IllegalStateException.

 DropdownMenuItem(onClick = {
                Toast.makeText(context,"Clear",Toast.LENGTH_SHORT).show()
            }) {
                LazyColumn {
                    item {
                        Text("Clear")
                    }
                }

            }
java.lang.IllegalStateException: Asking for intrinsic measurements of SubcomposeLayout layouts is not supported. This includes components that are built on top of SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate this:
    - if intrinsic measurements are used to achieve 'match parent' sizing,, consider replacing the parent of the component with a custom layout which controls the order in which children are measured, making intrinsic measurement not needed
    - adding a size modifier to the component, in order to fast return the queried intrinsic measurement.
    

2.2. Jetpack compose dropdown positioning

DropdownMenu changes its positioning depending on the available space, always trying to be fully visible.

You can provide offset (x and y) to adjust the positioning of the menu. Note the offset will be applied in the direction in which the menu will decide to expand.

DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            Modifier.offset(10.dp, 10.dp)
        )

3. Conclusion

To sum up, we have learned about the Jetpack compose drop menu.

Leave a Reply

Your email address will not be published. Required fields are marked *