Material 3 Buttons in Android
Overview
Buttons enable users to take actions with a single tap.
Material 3 Buttons, using MaterialButton
, come in Default and Toggle variants with five styles (Elevated, Filled, Filled Tonal, Outlined, Text), supporting five sizes, shape morphing, and toggle functionality per the Material 3 Expressive update. They are used in dialogs, forms, cards, and toolbars, adhering to Material Design guidelines. This guide covers implementation, accessibility, and theming.
Getting Started
- Add Material Components for Android library dependency
- Use
Button
with Theme.Material3.*
for auto-inflation to MaterialButton
- Apply styles for Elevated, Filled, Filled Tonal, Outlined, or Text buttons
Accessibility
- Readable by TalkBack with auto-provided text labels
- Additional
android:contentDescription
usually unnecessary
- Ensure sufficient contrast for text and icons
Button Types
- Default Button: For actions like form submission, placed in dialogs, forms, cards, toolbars
- Toggle Button: For binary selections (e.g., Save, Favorite), changes shape/color when selected
- Styles: Elevated (shadowed), Filled (high prominence), Filled Tonal (moderate prominence), Outlined (medium emphasis), Text (low emphasis)
- Sizes: Extra Small, Small (default), Medium, Large, Extra Large
Elevated Button
- Shadowed for separation from patterned backgrounds
- Use sparingly to avoid shadow creep
Example
<Button
style="@style/Widget.Material3.Button.ElevatedButton"
android:id="@+id/elevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Elevated button"
app:icon="@drawable/ic_add_24dp"/>
val elevatedButton = findViewById<Button>(R.id.elevatedButton)
elevatedButton.setOnClickListener {
// Respond to button press
}
Elevated Button Anatomy
Component |
Description |
Default State |
Toggle Selected State |
Container |
Low-elevation, shadowed surface |
colorSurfaceContainerLow, round shape |
Morphs to square shape |
Label Text |
Sentence case, centered |
colorOnSurface |
colorOnSurface, may change label |
Icon |
Optional, 24dp, 8dp padding from text |
colorOnSurface, outlined |
colorOnSurface, filled or bold |
Filled Button
- High prominence for primary actions
- Default style if no style is set
Example
<Button
android:id="@+id/filledButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Filled button"
app:icon="@drawable/ic_add_24dp"/>
val filledButton = findViewById<Button>(R.id.filledButton)
filledButton.setOnClickListener {
// Respond to button press
}
Filled Button Anatomy
Component |
Description |
Default State |
Toggle Selected State |
Container |
Solid fill, 2dp elevation |
colorPrimary, round shape |
Morphs to square shape |
Label Text |
Sentence case, centered |
colorOnPrimary |
colorOnPrimary, may change label |
Icon |
Optional, 24dp, 8dp padding from text |
colorOnPrimary, outlined |
colorOnPrimary, filled or bold |
Filled Tonal Button
- Moderate prominence for secondary actions
- Lighter fill than Filled button
Example
<Button
style="@style/Widget.Material3.Button.TonalButton"
android:id="@+id/filledTonalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Filled tonal button"
app:icon="@drawable/ic_add_24dp"/>
val filledTonalButton = findViewById<Button>(R.id.filledTonalButton)
filledTonalButton.setOnClickListener {
// Respond to button press
}
Filled Tonal Button Anatomy
Component |
Description |
Default State |
Toggle Selected State |
Container |
Lighter fill, 2dp elevation |
colorSecondaryContainer, round shape |
Morphs to square shape |
Label Text |
Sentence case, centered |
colorOnSecondaryContainer |
colorOnSecondaryContainer, may change label |
Icon |
Optional, 24dp, 8dp padding from text |
colorOnSecondaryContainer, outlined |
colorOnSecondaryContainer, filled or bold |
Outlined Button
- Medium emphasis for non-primary actions
- Used for options like "See all" or "Cancel"
Example
<Button
style="@style/Widget.Material3.Button.OutlinedButton"
android:id="@+id/outlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Outlined button"
app:icon="@drawable/ic_add_24dp"/>
val outlinedButton = findViewById<Button>(R.id.outlinedButton)
outlinedButton.setOnClickListener {
// Respond to button press
}
Outlined Button Anatomy
Component |
Description |
Default State |
Toggle Selected State |
Container |
Transparent fill, 1dp stroke, 0dp elevation |
Transparent, colorOnSurface stroke, round shape |
Morphs to square shape |
Label Text |
Sentence case, centered |
colorOnSurface |
colorOnSurface, may change label |
Icon |
Optional, 24dp, 8dp padding from text |
colorOnSurface, outlined |
colorOnSurface, filled or bold |
Text Button
- Low emphasis for multiple options
- Not used for toggle buttons
Example
<Button
style="@style/Widget.Material3.Button.TextButton"
android:id="@+id/textButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text button"
app:icon="@drawable/ic_add_24dp"/>
val textButton = findViewById<Button>(R.id.textButton)
textButton.setOnClickListener {
// Respond to button press
}
Text Button Anatomy
Component |
Description |
Default State |
Toggle Selected State |
Container |
Transparent, no border, 0dp elevation |
Transparent, round shape |
Not applicable |
Label Text |
Sentence case, centered |
colorOnSurface |
Not applicable |
Icon |
Optional, 24dp, 8dp padding from text |
colorOnSurface, outlined |
Not applicable |
Toggle Button
- Used for binary selections (e.g., Save, Favorite)
- Changes shape (round to square), color, and icon style when selected
- Not applicable to Text buttons
Example
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:id="@+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toggle button"
app:icon="@drawable/ic_favorite_24dp"/>
val toggleButton = findViewById<Button>(R.id.toggleButton)
toggleButton.isChecked = false
toggleButton.setOnCheckedChangeListener { button, isChecked ->
if (isChecked) {
button.setIconResource(R.drawable.ic_favorite_filled_24dp)
button.text = "Favorited"
} else {
button.setIconResource(R.drawable.ic_favorite_24dp)
button.text = "Favorite"
}
}
Optical Centering
- Offsets content for asymmetric shapes
- Enable with
setOpticalCenterEnabled(true)
, disabled by default
val button = findViewById<Button>(R.id.elevatedButton)
button.setOpticalCenterEnabled(true)
Theming
- Customize color, typography, and shape
- Use
res/values/styles.xml
for theming
Example
<style name="Theme.App" parent="Theme.Material3.*">
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="textAppearanceLabelLarge">@style/TextAppearance.App.Button</item>
<item name="shapeCornerFamily">cut</item>
</style>
<style name="TextAppearance.App.Button" parent="TextAppearance.Material3.LabelLarge">
<item name="fontFamily">@font/rubik</item>
<item name="android:fontFamily">@font/rubik</item>
</style>
<style name="Theme.App" parent="Theme.Material3.*">
<item name="materialButtonStyle">@style/Widget.App.Button</item>
<item name="materialButtonOutlinedStyle">@style/Widget.App.Button.OutlinedButton</item>
<item name="borderlessButtonStyle">@style/Widget.App.Button.TextButton</item>
</style>
<style name="Widget.App.Button" parent="Widget.Material3.Button">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Button</item>
<item name="android:textAppearance">@style/TextAppearance.App.Button</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="Widget.App.Button.OutlinedButton" parent="Widget.Material3.Button.OutlinedButton">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.TextButton</item>
<item name="android:textAppearance">@style/TextAppearance.App.Button</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="Widget.App.Button.TextButton" parent="Widget.Material3.Button.TextButton">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.TextButton</item>
<item name="android:textAppearance">@style/TextAppearance.App.Button</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="ThemeOverlay.App.Button" parent="ThemeOverlay.Material3.Button">
<item name="colorContainer">@color/shrine_pink_100</item>
<item name="colorOnContainer">@color/shrine_pink_900</item>
</style>
<style name="ThemeOverlay.App.Button.TextButton" parent="ThemeOverlay.Material3.Button.TextButton">
<item name="colorOnContainer">@color/shrine_pink_900</item>
</style>
<style name="ShapeAppearance.App.Button" parent="">
<item name="cornerFamily">cut</item>
<item name="cornerSize">4dp</item>
</style>
Material Design Documentation
- Adheres to Material Design guidelines for Buttons
- Covers design, behavior, theming specifications
- Includes structure, accessibility, expressive updates
- Refer to Material Design documentation for full details
FAQ
What are Material 3 buttons?
- UI components for actions or choices with a tap
How many types of Material 3 buttons are there?
- Two variants: Default and Toggle; five styles: Elevated, Filled, Filled Tonal, Outlined, Text
When should I use a Filled button?
- Use for primary, high-emphasis actions like form submission
How do I make buttons accessible?
- Use clear text labels; TalkBack auto-reads them
Can I customize button appearance?
- Yes, theme via
res/values/styles.xml
What’s the difference between Filled and Filled Tonal buttons?
- Filled: Solid fill for primary actions; Filled Tonal: Lighter fill for secondary actions
How do I add the Material 3 library?
- Include Material Components for Android library
Are there updates for the latest standards?
- Reflects latest Material 3 standards, including expressive updates
Rated 4.94 by 169 users • 0views