
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
A 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.
DropdownMenuItem
– matches the material design specification- 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") } } } }

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.