Material 3 Menus
Overview
Menus display a list of choices on temporary surfaces, triggered by user interactions.
Material 3 Menus support two variants: Dropdown (overflow, context, popup, list popup window) and Exposed Dropdown. They are less prominent than selection controls like radio buttons, ideal for compact option lists. This guide covers implementation, accessibility, and theming.
Getting Started
- Add Material Components for Android library dependency
- Use XML menu resources for Dropdown menus
- Use
TextInputLayout
with AutoCompleteTextView
for Exposed Dropdown menus
- Apply
Theme.Material3.*
for styling
Accessibility
- Dropdown menu text is auto-readable by TalkBack
- Use labels and helper text in
TextInputLayout
for Exposed Dropdown
- Set
android:contentDescription
for custom accessibility needs
Behavior and Configuration
- Configure Dropdown menus via XML resources or programmatically
- Set Exposed Dropdown items via adapters or
setSimpleItems
- Handle selections with listeners
val button = findViewById<Button>(R.id.menu_button)
button.setOnClickListener {
val popup = PopupMenu(context, it)
popup.menuInflater.inflate(R.menu.popup_menu, popup.menu)
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.option_1 -> { /* Handle option 1 */ true }
R.id.option_2 -> { /* Handle option 2 */ true }
else -> false
}
}
popup.show()
}
Menu Variants
- Dropdown: Temporary list for overflow, context, or popup menus
- Exposed Dropdown: Text field with dropdown options
Dropdown Menu
- Triggered by buttons, icons, or long presses
- Supports list items, icons, and dividers
Example
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/show_menu"/>
<!-- res/menu/popup_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/option_1"
android:title="@string/option_1"/>
<item
android:id="@+id/option_2"
android:title="@string/option_2"/>
</menu>
val button = findViewById<Button>(R.id.menu_button)
button.setOnClickListener {
val popup = PopupMenu(context, it)
popup.menuInflater.inflate(R.menu.popup_menu, popup.menu)
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.option_1 -> { /* Handle option 1 */ true }
R.id.option_2 -> { /* Handle option 2 */ true }
else -> false
}
}
popup.show()
}
Dropdown Menu Anatomy
Component |
Description |
Behavior |
Container |
Temporary surface, colorSurfaceContainer, 3dp elevation |
Holds list items, appears on trigger |
List Item |
Selectable option, colorOnSurface |
Triggers action on selection |
Leading Icon |
Optional, colorOnSurface |
Enhances item context, left-aligned |
Trailing Icon |
Optional, colorOnSurface |
Indicates status, right-aligned |
Trailing Text |
Optional, colorOnSurfaceVariant |
Provides additional info, right-aligned |
Divider |
Optional, colorOutline |
Separates groups of items |
Exposed Dropdown Menu
- Combines text field with dropdown list
- Suitable for forms or inline selections
Example
<com.google.android.material.textfield.TextInputLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/menu"
style="@style/Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/label">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
app:simpleItems="@array/simple_items"/>
</com.google.android.material.textfield.TextInputLayout>
val textField = findViewById<com.google.android.material.textfield.TextInputLayout>(R.id.menu)
val autoComplete = textField.editText as com.google.android.material.textfield.MaterialAutoCompleteTextView
autoComplete.setSimpleItems(arrayOf("Item 1", "Item 2"))
autoComplete.setText("Item 1", false)
Exposed Dropdown Menu Anatomy
Component |
Description |
Behavior |
Container |
TextInputLayout , colorSurfaceContainer |
Holds dropdown list, shows on focus |
Label |
Hint text, colorOnSurface |
Describes field purpose |
Selection Text |
Selected item, colorOnSurface |
Displays current selection |
Trailing Icon |
Dropdown arrow, colorOnSurface |
Toggles dropdown visibility |
Attributes and Usage
Element |
Attribute |
Related Method(s) |
Default Value |
Usage Description |
Dropdown Container |
android:popupMenuBackground |
N/A |
?attr/popupMenuBackground |
Sets background color |
Dropdown Container |
android:popupElevation |
N/A |
3dp |
Sets elevation |
Dropdown Text |
android:title |
Menu.add , Menu.getItem |
null |
Sets item text |
Exposed Dropdown Container |
app:dropDownBackgroundTint |
setDropDownBackgroundTint |
?attr/colorSurfaceContainer |
Sets dropdown background color |
Exposed Dropdown Text |
android:text |
setText , getText |
null |
Sets selected text |
Theming Menus
- Customize colors, typography, and shapes
- Use
res/values/styles.xml
for theming
Example
<style name="Theme.App" parent="Theme.Material3.*">
<item name="popupMenuStyle">@style/Widget.App.PopupMenu</item>
<item name="textInputStyle">@style/Widget.App.TextInputLayout</item>
</style>
<style name="Widget.App.PopupMenu" parent="Widget.Material3.PopupMenu">
<item name="android:popupBackground">@color/shrine_pink_50</item>
<item name="textAppearanceLargePopupMenu">@style/TextAppearance.App.BodyLarge</item>
</style>
<style name="Widget.App.TextInputLayout" parent="Widget.Material3.TextInputLayout.FilledBox.ExposedDropdownMenu">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.ExposedDropdownMenu</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.SmallComponent</item>
</style>
<style name="ThemeOverlay.App.ExposedDropdownMenu" parent="">
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnSurface">@color/shrine_pink_900</item>
</style>
<style name="TextAppearance.App.BodyLarge" parent="TextAppearance.Material3.BodyLarge">
<item name="android:textColor">@color/shrine_pink_900</item>
</style>
<style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.Material3.SmallComponent">
<item name="cornerFamily">cut</item>
<item name="cornerSize">4dp</item>
</style>
Menu Variants Comparison
Variant |
Pros |
Cons |
Image |
Dropdown |
- Compact, temporary display
- Supports icons and dividers
|
- Limited to small option sets
|
|
Exposed Dropdown |
- Integrated with text input
- Ideal for forms
|
- Requires more screen space
|
|
Material Design Documentation
- Adheres to Material Design guidelines for Menus
- Covers design, behavior, theming specifications
- Includes accessibility and variant support
- Refer to Material Design documentation for full details
FAQ
What are Material 3 Menus?
- Temporary surfaces for selecting options
How many menu variants are there?
- Two: Dropdown and Exposed Dropdown
When to use Exposed Dropdown Menus?
- Use for inline selections in forms
How to make menus accessible?
- Use labels or
contentDescription
for TalkBack
Can I customize menu appearance?
- Yes, theme via
res/values/styles.xml
How to add the Material 3 library?
- Include Material Components for Android library
Are there updates for the latest standards?
- Reflects latest Material 3 standards for Menus