DropdownMenu
Functions summary
Unit |
@Composable |
Cmn
android
|
Functions
DropdownMenu
@Composable
fun DropdownMenu(
expanded: Boolean,
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
offset: DpOffset = DpOffset(0.dp, 0.dp),
scrollState: ScrollState = rememberScrollState(),
properties: PopupProperties = MenuDefaults.DefaultMenuProperties,
shape: Shape = MenuDefaults.shape,
containerColor: Color = MenuDefaults.containerColor,
tonalElevation: Dp = MenuDefaults.TonalElevation,
shadowElevation: Dp = MenuDefaults.ShadowElevation,
border: BorderStroke? = null,
content: @Composable ColumnScope.() -> Unit
): Unit
Menus display a list of choices on a temporary surface. They appear when users interact with a button, action, or other control.

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'. Note that a DropdownMenu by itself will not take up any space in a layout, as the menu is displayed in a separate window, on top of other content.
The content of a DropdownMenu will typically be DropdownMenuItems, as well as custom content. Using DropdownMenuItems will result in a menu that matches the Material specification for menus. Also note that the content is placed inside a scrollable Column, so using a androidx.compose.foundation.lazy.LazyColumn as the root layout inside content is unsupported.
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.
DropdownMenu changes its positioning depending on the available space, always trying to be fully visible. Depending on layout direction, first it will try to align its start to the start of its parent, then its end to the end of its parent, and then to the edge of the window. Vertically, it will try to align its top to the bottom of its parent, then its bottom to top of its parent, and then to the edge of the window.
An offset can be provided to adjust the positioning of the menu for cases when the layout bounds of its parent do not coincide with its visual bounds.
Example usage:
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Email import androidx.compose.material.icons.outlined.MoreVert import androidx.compose.material.icons.outlined.Settings import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.PlainTooltip import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextAlign var expanded by remember { mutableStateOf(false) } Box(modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.TopStart)) { // Icon button should have a tooltip associated with it for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip text is // not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = "Localized description" } ) { Text("Localized description") } }, state = rememberTooltipState(), ) { IconButton(onClick = { expanded = true }) { Icon(Icons.Default.MoreVert, contentDescription = "Localized description") } } DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) { DropdownMenuItem( text = { Text("Edit") }, onClick = { /* Handle edit! */ }, leadingIcon = { Icon(Icons.Outlined.Edit, contentDescription = null) }, ) DropdownMenuItem( text = { Text("Settings") }, onClick = { /* Handle settings! */ }, leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = null) }, ) HorizontalDivider() DropdownMenuItem( text = { Text("Send Feedback") }, onClick = { /* Handle send feedback! */ }, leadingIcon = { Icon(Icons.Outlined.Email, contentDescription = null) }, trailingIcon = { Text("F11", textAlign = TextAlign.Center) }, ) } }
Example usage with a ScrollState to control the menu items scroll position:
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.MoreVert import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.PlainTooltip import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics var expanded by remember { mutableStateOf(false) } val scrollState = rememberScrollState() Box(modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.TopStart)) { // Icon button should have a tooltip associated with it for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip text is // not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = "Localized description" } ) { Text("Localized description") } }, state = rememberTooltipState(), ) { IconButton(onClick = { expanded = true }) { Icon(Icons.Default.MoreVert, contentDescription = "Localized description") } } DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, scrollState = scrollState, ) { repeat(30) { DropdownMenuItem( text = { Text("Item ${it + 1}") }, onClick = { /* TODO */ }, leadingIcon = { Icon(Icons.Outlined.Edit, contentDescription = null) }, ) } } LaunchedEffect(expanded) { if (expanded) { // Scroll to show the bottom menu items. scrollState.scrollTo(scrollState.maxValue) } } }
| Parameters | |
|---|---|
expanded: Boolean |
whether the menu is expanded or not |
onDismissRequest: () -> Unit |
called when the user requests to dismiss the menu, such as by tapping outside the menu's bounds |
modifier: Modifier = Modifier |
|
offset: DpOffset = DpOffset(0.dp, 0.dp) |
|
scrollState: ScrollState = rememberScrollState() |
a |
properties: PopupProperties = MenuDefaults.DefaultMenuProperties |
|
shape: Shape = MenuDefaults.shape |
the shape of the menu |
containerColor: Color = MenuDefaults.containerColor |
the container color of the menu |
tonalElevation: Dp = MenuDefaults.TonalElevation |
when |
shadowElevation: Dp = MenuDefaults.ShadowElevation |
the elevation for the shadow below the menu |
border: BorderStroke? = null |
the border to draw around the container of the menu. Pass |
content: @Composable ColumnScope.() -> Unit |
the content of this dropdown menu, typically a |