DropdownMenuItem

Functions summary

Unit
@Composable
DropdownMenuItem(
    text: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    enabled: Boolean,
    colors: MenuItemColors,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?
)

Material Design dropdown menu

Cmn
android
Unit
@ExperimentalMaterial3ExpressiveApi
@Composable
DropdownMenuItem(
    onClick: () -> Unit,
    text: @Composable () -> Unit,
    shape: Shape,
    modifier: Modifier,
    leadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    enabled: Boolean,
    colors: MenuItemColors,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    supportingText: (@Composable () -> Unit)?
)

Material Design dropdown menu

Cmn
Unit
@ExperimentalMaterial3ExpressiveApi
@Composable
DropdownMenuItem(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    text: @Composable () -> Unit,
    shapes: MenuItemShapes,
    modifier: Modifier,
    leadingIcon: (@Composable () -> Unit)?,
    checkedLeadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    enabled: Boolean,
    colors: MenuItemColors,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    supportingText: (@Composable () -> Unit)?
)

Material Design dropdown menu

Cmn
Unit
@ExperimentalMaterial3ExpressiveApi
@Composable
DropdownMenuItem(
    selected: Boolean,
    onClick: () -> Unit,
    text: @Composable () -> Unit,
    shapes: MenuItemShapes,
    modifier: Modifier,
    leadingIcon: (@Composable () -> Unit)?,
    selectedLeadingIcon: (@Composable () -> Unit)?,
    trailingIcon: (@Composable () -> Unit)?,
    enabled: Boolean,
    colors: MenuItemColors,
    contentPadding: PaddingValues,
    interactionSource: MutableInteractionSource?,
    supportingText: (@Composable () -> Unit)?
)

Material Design dropdown menu

Cmn

Functions

@Composable
fun DropdownMenuItem(
    text: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    enabled: Boolean = true,
    colors: MenuItemColors = MenuDefaults.itemColors(),
    contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
    interactionSource: MutableInteractionSource? = null
): Unit

Material Design dropdown menu

Menus display a list of choices on a temporary surface. They appear when users interact with a button, action, or other control.

Dropdown menu
image

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.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 { 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) },
        )
    }
}
Parameters
text: @Composable () -> Unit

text of the menu item

onClick: () -> Unit

called when this menu item is clicked

modifier: Modifier = Modifier

the Modifier to be applied to this menu item

leadingIcon: (@Composable () -> Unit)? = null

optional leading icon to be displayed at the beginning of the item's text

trailingIcon: (@Composable () -> Unit)? = null

optional trailing icon to be displayed at the end of the item's text. This trailing icon slot can also accept Text to indicate a keyboard shortcut.

enabled: Boolean = true

controls the enabled state of this menu item. When false, this component will not respond to user input, and it will appear visually disabled and disabled to accessibility services.

colors: MenuItemColors = MenuDefaults.itemColors()

MenuItemColors that will be used to resolve the colors used for this menu item in different states. See MenuDefaults.itemColors.

contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding

the padding applied to the content of this menu item

interactionSource: MutableInteractionSource? = null

an optional hoisted MutableInteractionSource for observing and emitting Interactions for this menu item. You can use this to change the menu item's appearance or preview the menu item in different states. Note that if null is provided, interactions will still happen internally.

@ExperimentalMaterial3ExpressiveApi
@Composable
fun DropdownMenuItem(
    onClick: () -> Unit,
    text: @Composable () -> Unit,
    shape: Shape,
    modifier: Modifier = Modifier,
    leadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    enabled: Boolean = true,
    colors: MenuItemColors = MenuDefaults.itemColors(),
    contentPadding: PaddingValues = MenuDefaults.DropdownMenuSelectableItemContentPadding,
    interactionSource: MutableInteractionSource? = null,
    supportingText: (@Composable () -> Unit)? = null
): Unit

Material Design dropdown menu

Menus display a list of choices on a temporary surface. They appear when users interact with a button, action, or other control.

Dropdown menu
image

Parameters
onClick: () -> Unit

called when this menu item is clicked

text: @Composable () -> Unit

text of the menu item.

shape: Shape

Shape of this menu item. The shapes provided should be determined by the number of items in the group or menu as well as the item's position in the menu. Please use MenuDefaults.leadingItemShape for the first item in a list, MenuDefaults.middleItemShape for the middle items in a list, and MenuDefaults.trailingItemShape for the last item in a list.

modifier: Modifier = Modifier

the Modifier to be applied to this menu item.

leadingIcon: (@Composable () -> Unit)? = null

optional leading icon to be displayed when the item is unchecked.

trailingIcon: (@Composable () -> Unit)? = null

optional trailing icon to be displayed at the end of the item's text.

enabled: Boolean = true

controls the enabled state of this menu item. When false, this component will not respond to user input.

colors: MenuItemColors = MenuDefaults.itemColors()

MenuItemColors that will be used to resolve the colors for this menu item.

contentPadding: PaddingValues = MenuDefaults.DropdownMenuSelectableItemContentPadding

the padding applied to the content of this menu item.

interactionSource: MutableInteractionSource? = null

an optional hoisted MutableInteractionSource for observing and emitting Interactions for this menu item.

supportingText: (@Composable () -> Unit)? = null

optional supporting text of the menu item.

@ExperimentalMaterial3ExpressiveApi
@Composable
fun DropdownMenuItem(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    text: @Composable () -> Unit,
    shapes: MenuItemShapes,
    modifier: Modifier = Modifier,
    leadingIcon: (@Composable () -> Unit)? = null,
    checkedLeadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    enabled: Boolean = true,
    colors: MenuItemColors = MenuDefaults.selectableItemColors(),
    contentPadding: PaddingValues = MenuDefaults.DropdownMenuSelectableItemContentPadding,
    interactionSource: MutableInteractionSource? = null,
    supportingText: (@Composable () -> Unit)? = null
): Unit

Material Design dropdown menu

A menu item that changes its styling depending on the checked state.

This composable is suitable for menu items that represent an on/off setting, behaving like a checkbox or switch within the menu.

Dropdown menu
image

Example usage:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Info
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.Home
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.ButtonGroup
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuGroup
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.DropdownMenuPopup
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MenuDefaults
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.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.util.fastForEachIndexed

val groupInteractionSource = remember { MutableInteractionSource() }
var expanded by remember { mutableStateOf(false) }
var homeChecked by remember { mutableStateOf(false) }
val groupLabels = listOf("Modification", "Navigation")
val groupItemLabels = listOf(listOf("Edit", "Settings"), listOf("Home", "More Options"))
val groupItemLeadingIcons =
    listOf(
        listOf(Icons.Outlined.Edit, Icons.Outlined.Settings),
        listOf(null, Icons.Outlined.Info),
    )
val groupItemCheckedLeadingIcons =
    listOf(
        listOf(Icons.Filled.Edit, Icons.Filled.Settings),
        listOf(Icons.Filled.Check, Icons.Filled.Info),
    )
val groupItemTrailingIcons: List<List<ImageVector?>> =
    listOf(listOf(null, null), listOf(Icons.Outlined.Home, Icons.Outlined.MoreVert))
val groupItemCheckedTrailingIcons: List<List<ImageVector?>> =
    listOf(listOf(null, null), listOf(Icons.Filled.Home, Icons.Filled.MoreVert))
val groupItemSupportingText: List<List<String?>> =
    listOf(listOf("Edit mode", null), listOf(null, "Opens menu"))
val checked = remember {
    listOf(mutableStateListOf(false, false), mutableStateListOf(false, 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 { Text("Localized description") } },
        state = rememberTooltipState(),
    ) {
        IconButton(onClick = { expanded = true }) {
            Icon(Icons.Default.MoreVert, contentDescription = "Localized description")
        }
    }
    DropdownMenuPopup(expanded = expanded, onDismissRequest = { expanded = false }) {
        val groupCount = groupLabels.size
        groupLabels.fastForEachIndexed { groupIndex, label ->
            DropdownMenuGroup(
                shapes = MenuDefaults.groupShape(groupIndex, groupCount),
                interactionSource = groupInteractionSource,
            ) {
                MenuDefaults.Label { Text(label) }
                HorizontalDivider(
                    modifier = Modifier.padding(MenuDefaults.HorizontalDividerPadding)
                )
                val groupItemCount = groupItemLabels[groupIndex].size
                groupItemLabels[groupIndex].fastForEachIndexed { itemIndex, itemLabel ->
                    DropdownMenuItem(
                        text = { Text(itemLabel) },
                        supportingText =
                            groupItemSupportingText[groupIndex][itemIndex]?.let { supportingText
                                ->
                                { Text(supportingText) }
                            },
                        shapes = MenuDefaults.itemShape(itemIndex, groupItemCount),
                        leadingIcon =
                            groupItemLeadingIcons[groupIndex][itemIndex]?.let { iconData ->
                                {
                                    Icon(
                                        iconData,
                                        modifier = Modifier.size(MenuDefaults.LeadingIconSize),
                                        contentDescription = null,
                                    )
                                }
                            },
                        checkedLeadingIcon = {
                            Icon(
                                groupItemCheckedLeadingIcons[groupIndex][itemIndex],
                                modifier = Modifier.size(MenuDefaults.LeadingIconSize),
                                contentDescription = null,
                            )
                        },
                        trailingIcon =
                            if (checked[groupIndex][itemIndex]) {
                                groupItemCheckedTrailingIcons[groupIndex][itemIndex]?.let {
                                    iconData ->
                                    {
                                        Icon(
                                            iconData,
                                            modifier =
                                                Modifier.size(MenuDefaults.TrailingIconSize),
                                            contentDescription = null,
                                        )
                                    }
                                }
                            } else {
                                groupItemTrailingIcons[groupIndex][itemIndex]?.let { iconData ->
                                    {
                                        Icon(
                                            iconData,
                                            modifier =
                                                Modifier.size(MenuDefaults.TrailingIconSize),
                                            contentDescription = null,
                                        )
                                    }
                                }
                            },
                        checked = checked[groupIndex][itemIndex],
                        onCheckedChange = { checked[groupIndex][itemIndex] = it },
                    )
                }
            }

            if (groupIndex != groupCount - 1) {
                Spacer(Modifier.height(MenuDefaults.GroupSpacing))
            }
        }
        if (checked.last().last()) {
            DropdownMenuButtonGroup()
        }
    }
}
Parameters
checked: Boolean

whether this menu item is currently checked.

onCheckedChange: (Boolean) -> Unit

called when this menu item is clicked, with the new checked state.

text: @Composable () -> Unit

text of the menu item.

shapes: MenuItemShapes

MenuItemShapes that will be used to resolve the shapes for this menu item. The shape of this item is determined by the value of checked. The shapes provided should be determined by the number of items in the group or menu as well as the item's position in the menu. There is a convenience function that can be used to easily determine the shape to be used at MenuDefaults.itemShape

modifier: Modifier = Modifier

the Modifier to be applied to this menu item.

leadingIcon: (@Composable () -> Unit)? = null

optional leading icon to be displayed when the item is unchecked.

checkedLeadingIcon: (@Composable () -> Unit)? = null

optional leading icon to be displayed when the item is checked.

trailingIcon: (@Composable () -> Unit)? = null

optional trailing icon to be displayed at the end of the item's text.

enabled: Boolean = true

controls the enabled state of this menu item. When false, this component will not respond to user input.

colors: MenuItemColors = MenuDefaults.selectableItemColors()

MenuItemColors that will be used to resolve the colors for this menu item. There are two predefined MenuItemColors at MenuDefaults.selectableItemColors and MenuDefaults.selectableItemVibrantColors which you can use or modify.

contentPadding: PaddingValues = MenuDefaults.DropdownMenuSelectableItemContentPadding

the padding applied to the content of this menu item.

interactionSource: MutableInteractionSource? = null

an optional hoisted MutableInteractionSource for observing and emitting Interactions for this menu item.

supportingText: (@Composable () -> Unit)? = null

optional supporting text of the menu item.

@ExperimentalMaterial3ExpressiveApi
@Composable
fun DropdownMenuItem(
    selected: Boolean,
    onClick: () -> Unit,
    text: @Composable () -> Unit,
    shapes: MenuItemShapes,
    modifier: Modifier = Modifier,
    leadingIcon: (@Composable () -> Unit)? = null,
    selectedLeadingIcon: (@Composable () -> Unit)? = null,
    trailingIcon: (@Composable () -> Unit)? = null,
    enabled: Boolean = true,
    colors: MenuItemColors = MenuDefaults.selectableItemColors(),
    contentPadding: PaddingValues = MenuDefaults.DropdownMenuSelectableItemContentPadding,
    interactionSource: MutableInteractionSource? = null,
    supportingText: (@Composable () -> Unit)? = null
): Unit

Material Design dropdown menu

A menu item that changes its styling depending on the selected state.

This composable is suitable for menu items that represent an on/off setting, behaving like a radio button within the menu.

Dropdown menu
image

Example usage:

import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExposedDropdownMenuAnchorType
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier

val options: List<String> = SampleData.take(5)
var expanded by remember { mutableStateOf(false) }
val textFieldState = rememberTextFieldState(options[0])
var checkedIndex: Int? by remember { mutableStateOf(null) }

ExposedDropdownMenuBox(expanded = expanded, onExpandedChange = { expanded = it }) {
    TextField(
        // The `menuAnchor` modifier must be passed to the text field to handle
        // expanding/collapsing the menu on click. A read-only text field has
        // the anchor type `PrimaryNotEditable`.
        modifier = Modifier.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable),
        state = textFieldState,
        readOnly = true,
        lineLimits = TextFieldLineLimits.SingleLine,
        label = { Text("Label") },
        trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
        colors = ExposedDropdownMenuDefaults.textFieldColors(),
    )
    ExposedDropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false },
        containerColor = MenuDefaults.groupStandardContainerColor,
        shape = MenuDefaults.standaloneGroupShape,
    ) {
        val optionCount = options.size
        options.forEachIndexed { index, option ->
            DropdownMenuItem(
                shapes = MenuDefaults.itemShape(index, optionCount),
                text = { Text(option, style = MaterialTheme.typography.bodyLarge) },
                selected = index == checkedIndex,
                onClick = {
                    textFieldState.setTextAndPlaceCursorAtEnd(option)
                    checkedIndex = index
                },
                selectedLeadingIcon = {
                    Icon(
                        Icons.Filled.Check,
                        modifier = Modifier.size(MenuDefaults.LeadingIconSize),
                        contentDescription = null,
                    )
                },
                contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
            )
        }
    }
}
Parameters
selected: Boolean

whether this menu item is currently selected.

onClick: () -> Unit

called when this menu item is clicked.

text: @Composable () -> Unit

text of the menu item.

shapes: MenuItemShapes

MenuItemShapes that will be used to resolve the shapes for this menu item. The shape of this item is determined by the value of selected. The shapes provided should be determined by the number of items in the group or menu as well as the item's position in the menu. There is a convenience function that can be used to easily determine the shape to be used at MenuDefaults.itemShape

modifier: Modifier = Modifier

the Modifier to be applied to this menu item.

leadingIcon: (@Composable () -> Unit)? = null

optional leading icon to be displayed when the item is unchecked.

selectedLeadingIcon: (@Composable () -> Unit)? = null

optional leading icon to be displayed when the item is selected.

trailingIcon: (@Composable () -> Unit)? = null

optional trailing icon to be displayed at the end of the item's text.

enabled: Boolean = true

controls the enabled state of this menu item. When false, this component will not respond to user input.

colors: MenuItemColors = MenuDefaults.selectableItemColors()

MenuItemColors that will be used to resolve the colors for this menu item. There are two predefined MenuItemColors at MenuDefaults.selectableItemColors and MenuDefaults.selectableItemVibrantColors which you can use or modify.

contentPadding: PaddingValues = MenuDefaults.DropdownMenuSelectableItemContentPadding

the padding applied to the content of this menu item.

interactionSource: MutableInteractionSource? = null

an optional hoisted MutableInteractionSource for observing and emitting Interactions for this menu item.

supportingText: (@Composable () -> Unit)? = null

optional supporting text of the menu item.