docs/components/CommonButton.md
Buttons allow users to take actions, and make choices, with a single tap. There are two variants of common buttons.
There are five button styles, in order of emphasis:
Buttons have default and toggle behaviors:
A. Default button
B. Toggle (unselected)
C. Toggle (selected)
Note: Images use various dynamic color schemes.
More details on anatomy items in the component guidelines.
Before you can use Material3Expressive component styles, follow the
Material3Expressive themes setup instructions.
Buttons now have a wider variety of shapes and sizes, toggle functionality, and can change shape when selected More on M3 Expressive
Types and naming:
Shapes:
Sizes:
New padding for small buttons:
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
By default, the filled button is uncheckable. To make it checkable, enable the
android:checkable attribute in style or layout.
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
android:checkable="true"/>
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
By default, the tonal button is uncheckable. To make it checkable, enable the
android:checkable attribute in style or layout.
<Button
style="?attr/materialButtonTonalStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
android:checkable="true"/>
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
By default, the outlined button is uncheckable. To make it checkable, enable the
android:checkable attribute in style or layout.
<Button
style="?attr/materialButtonOutlinedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
android:checkable="true"/>
The text button appears as only text until pressed. It does not have a solid fill or outline by default.
<Button
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"/>
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
By default, the elevated button is uncheckable. To make it checkable, enable the
android:checkable attribute in style or layout.
<Button
style="?attr/materialButtonElevatedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
android:checkable="true"/>
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
Icons visually communicate the button’s action and help draw attention. They should be placed on the leading side of the button, before the label text.
<Button
style="@style/Widget.Material3Expressive.Button.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
app:icon="@drawable/ic_dialogs_24px"
android:checkable="true"/>
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"/>
| Default <div style="width:250px"></div> | Checked <div style="width:250px"></div> | Unchecked <div style="width:250px"></div> |
|---|---|---|
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
app:materialSizeOverlay="@style/SizeOverlay.Material3Expressive.Button.{Small}.Square"/>
Note: Images below show the label buttons in different sizes relatively. The actual sizes in px on mobile devices depends on the screen pixel density.
<details><summary><h5>Extra small</h5></summary><Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
app:materialSizeOverlay="@style/SizeOverlay.Material3Expressive.Button.Xsmall"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
app:materialSizeOverlay="@style/SizeOverlay.Material3Expressive.Button.Medium"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
app:materialSizeOverlay="@style/SizeOverlay.Material3Expressive.Button.Large"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
app:materialSizeOverlay="@style/SizeOverlay.Material3Expressive.Button.Xlarge"/>
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Text label | android:text | setText | |
getText | null | ||
| Color | android:textColor | setTextColor | |
getTextColor | ?attr/colorOnSurface (see all states) | ||
| Typography | android:textAppearance | setTextAppearance | ?attr/textAppearanceLabelLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:backgroundTint | setBackgroundColor | |
setBackgroundTintList | |||
getBackgroundTintList | ?attr/colorSurfaceContainerLow (see all states) | ||
| Stroke color | app:strokeColor | setStrokeColor | |
setStrokeColorResource | |||
getStrokeColor | null | ||
| Stroke width | app:strokeWidth | setStrokeWidth | |
setStrokeWidthResource | |||
getStrokeWidth | 0dp | ||
| Shape | app:shapeAppearance | setShapeAppearanceModel | |
getShapeAppearanceModel | ShapeAppearance.M3.Sys.Shape.Corner.Full | ||
| Elevation | app:elevation | setElevation | |
getElevation | 1dp | ||
| Ripple color | app:rippleColor | setRippleColor | |
setRippleColorResource | |||
getRippleColor | ?attr/colorOnSurface at 16% opacity (see all states) |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Icon | app:icon | setIcon | |
setIconResource | |||
getIcon | null | ||
| Color | app:iconTint | setIconTint | |
setIconTintResource | |||
getIconTint | ?attr/colorOnSurface (see all states) | ||
| Size | app:iconSize | setIconSize | |
getIconSize | wrap_content | ||
| Gravity (position relative to text label) | app:iconGravity | setIconGravity | |
getIconGravity | start | ||
| Padding (space between icon and text label) | app:iconPadding | setIconPadding | |
getIconPadding | 8dp | ||
| Secondary icon | app:secondaryIcon | setSecondaryIcon | |
setSecondaryIconResource | |||
getSecondaryIcon | null | ||
| Secondary icon gravity | app:secondaryIconGravity | setSecondaryIconGravity | |
gettSecondaryIconGravity | end |
| Element | Style |
|---|---|
| Default style | Widget.Material3.Button.ElevatedButton |
| Icon style | Widget.Material3.Button.ElevatedButton.Icon |
Default style theme attribute: ?attr/materialButtonElevatedStyle
See the full list of styles and attrs.
</details> <details> <summary><h3>Filled button</h3></summary>| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Text label | android:text | setText | |
getText | null | ||
| Color | android:textColor | setTextColor | |
getTextColor | ?attr/colorOnPrimary (see all states) | ||
| Typography | android:textAppearance | setTextAppearance | ?attr/textAppearanceLabelLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:backgroundTint | setBackgroundColor | |
setBackgroundTintList | |||
getBackgroundTintList | ?attr/colorPrimary (see all states) | ||
| Stroke color | app:strokeColor | setStrokeColor | |
setStrokeColorResource | |||
getStrokeColor | null | ||
| Stroke width | app:strokeWidth | setStrokeWidth | |
setStrokeWidthResource | |||
getStrokeWidth | 0dp | ||
| Shape | app:shapeAppearance | setShapeAppearanceModel | |
getShapeAppearanceModel | ShapeAppearance.M3.Sys.Shape.Corner.Full | ||
| Elevation | app:elevation | setElevation | |
getElevation | 2dp | ||
| Ripple color | app:rippleColor | setRippleColor | |
setRippleColorResource | |||
getRippleColor | ?attr/colorOnPrimary at 16% opacity (see all states) |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Icon | app:icon | setIcon | |
setIconResource | |||
getIcon | null | ||
| Color | app:iconTint | setIconTint | |
setIconTintResource | |||
getIconTint | ?attr/colorOnPrimary (see all states) | ||
| Size | app:iconSize | setIconSize | |
getIconSize | wrap_content | ||
| Gravity (position relative to text label) | app:iconGravity | setIconGravity | |
getIconGravity | start | ||
| Padding (space between icon and text label) | app:iconPadding | setIconPadding | |
getIconPadding | 8dp | ||
| Secondary icon | app:secondaryIcon | setSecondaryIcon | |
setSecondaryIconResource | |||
getSecondaryIcon | null | ||
| Secondary icon gravity | app:secondaryIconGravity | setSecondaryIconGravity | |
gettSecondaryIconGravity | end |
| Element | Style |
|---|---|
| Default style | Widget.Material3.Button |
| Icon style | Widget.Material3.Button.Icon |
| Unelevated style | Widget.Material3.Button.UnelevatedButton |
| Unelevated icon style | Widget.Material3.Button.UnelevatedButton.Icon |
Default style theme attribute: ?attr/materialButtonStyle
See the full list of styles and attrs.
</details> <details> <summary><h3>Filled tonal button</h3></summary>| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Text label | android:text | setText | |
getText | null | ||
| Color | android:textColor | setTextColor | |
getTextColor | ?attr/colorOnSecondaryContainer (see all states) | ||
| Typography | android:textAppearance | setTextAppearance | ?attr/textAppearanceLabelLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:backgroundTint | setBackgroundColor | |
setBackgroundTintList | |||
getBackgroundTintList | ?attr/colorSecondaryContainer (see all states) | ||
| Stroke color | app:strokeColor | setStrokeColor | |
setStrokeColorResource | |||
getStrokeColor | null | ||
| Stroke width | app:strokeWidth | setStrokeWidth | |
setStrokeWidthResource | |||
getStrokeWidth | 0dp | ||
| Shape | app:shapeAppearance | setShapeAppearanceModel | |
getShapeAppearanceModel | ShapeAppearance.M3.Sys.Shape.Corner.Full | ||
| Elevation | app:elevation | setElevation | |
getElevation | 2dp | ||
| Ripple color | app:rippleColor | setRippleColor | |
setRippleColorResource | |||
getRippleColor | ?attr/colorOnSecondaryContainer at 16% opacity (see all states) |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Icon | app:icon | setIcon | |
setIconResource | |||
getIcon | null | ||
| Color | app:iconTint | setIconTint | |
setIconTintResource | |||
getIconTint | ?attr/colorOnSecondaryContainer (see all states) | ||
| Size | app:iconSize | setIconSize | |
getIconSize | wrap_content | ||
| Gravity (position relative to text label) | app:iconGravity | setIconGravity | |
getIconGravity | start | ||
| Padding (space between icon and text label) | app:iconPadding | setIconPadding | |
getIconPadding | 8dp | ||
| Secondary icon | app:secondaryIcon | setSecondaryIcon | |
setSecondaryIconResource | |||
getSecondaryIcon | null | ||
| Secondary icon gravity | app:secondaryIconGravity | setSecondaryIconGravity | |
gettSecondaryIconGravity | end |
| Element | Style |
|---|---|
| Default style | Widget.Material3.Button.TonalButton |
| Icon style | Widget.Material3.Button.TonalButton.Icon |
Default style theme attribute: ?attr/materialButtonTonalStyle
See the full list of styles and attrs.
</details> <details> <summary><h3>Outlined button</h3></summary>| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Text label | android:text | setText | |
getText | null | ||
| Color | android:textColor | setTextColor | |
getTextColor | ?attr/colorOnSurface (see all states) | ||
| Typography | android:textAppearance | setTextAppearance | ?attr/textAppearanceLabelLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:backgroundTint | setBackgroundColor | |
setBackgroundTintList | |||
getBackgroundTintList | @android:color/transparent (see all states) | ||
| Stroke color | app:strokeColor | setStrokeColor | |
setStrokeColorResource | |||
getStrokeColor | ?attr/colorOnSurface at 12% opacity (see all states) | ||
| Stroke width | app:strokeWidth | setStrokeWidth | |
setStrokeWidthResource | |||
getStrokeWidth | 1dp | ||
| Shape | app:shapeAppearance | setShapeAppearanceModel | |
getShapeAppearanceModel | ShapeAppearance.M3.Sys.Shape.Corner.Full | ||
| Elevation | app:elevation | setElevation | |
getElevation | 0dp | ||
| Ripple color | app:rippleColor | setRippleColor | |
setRippleColorResource | |||
getRippleColor | ?attr/colorOnSurface at 16% opacity (see all states) |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Icon | app:icon | setIcon | |
setIconResource | |||
getIcon | null | ||
| Color | app:iconTint | setIconTint | |
setIconTintResource | |||
getIconTint | ?attr/colorOnSurface (see all states) | ||
| Size | app:iconSize | setIconSize | |
getIconSize | wrap_content | ||
| Gravity (position relative to text label) | app:iconGravity | setIconGravity | |
getIconGravity | start | ||
| Padding (space between icon and text label) | app:iconPadding | setIconPadding | |
getIconPadding | 8dp | ||
| Secondary icon | app:secondaryIcon | setSecondaryIcon | |
setSecondaryIconResource | |||
getSecondaryIcon | null | ||
| Secondary icon gravity | app:secondaryIconGravity | setSecondaryIconGravity | |
gettSecondaryIconGravity | end |
| Element | Style |
|---|---|
| Default style | Widget.Material3.Button.OutlinedButton |
| Icon style | Widget.Material3.Button.OutlinedButton.Icon |
Default style theme attribute: ?attr/materialButtonOutlinedStyle
See the full list of styles and attrs.
</details> <details> <summary><h3>Text button</h3></summary>| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Text label | android:text | setText | |
getText | null | ||
| Color | android:textColor | setTextColor | |
getTextColor | ?attr/colorOnSurface (see all states) | ||
| Typography | android:textAppearance | setTextAppearance | ?attr/textAppearanceLabelLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:backgroundTint | setBackgroundColor | |
setBackgroundTintList | |||
getBackgroundTintList | @android:color/transparent (see all states) | ||
| Stroke color | app:strokeColor | setStrokeColor | |
setStrokeColorResource | |||
getStrokeColor | null | ||
| Stroke width | app:strokeWidth | setStrokeWidth | |
setStrokeWidthResource | |||
getStrokeWidth | 0dp | ||
| Shape | app:shapeAppearance | setShapeAppearanceModel | |
getShapeAppearanceModel | ShapeAppearance.M3.Sys.Shape.Corner.Full | ||
| Elevation | app:elevation | setElevation | |
getElevation | 0dp | ||
| Ripple color | app:rippleColor | setRippleColor | |
setRippleColorResource | |||
getRippleColor | ?attr/colorOnSurface at 16% opacity (see all states) |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Icon | app:icon | setIcon | |
setIconResource | |||
getIcon | null | ||
| Color | app:iconTint | setIconTint | |
setIconTintResource | |||
getIconTint | ?attr/colorOnSurface (see all states) | ||
| Size | app:iconSize | setIconSize | |
getIconSize | wrap_content | ||
| Gravity (position relative to text label) | app:iconGravity | setIconGravity | |
getIconGravity | start | ||
| Padding (space between icon and text label) | app:iconPadding | setIconPadding | |
getIconPadding | 8dp | ||
| Secondary icon | app:secondaryIcon | setSecondaryIcon | |
setSecondaryIconResource | |||
getSecondaryIcon | null | ||
| Secondary icon gravity | app:secondaryIconGravity | setSecondaryIconGravity | |
gettSecondaryIconGravity | end |
| Element | Style |
|---|---|
| Default style | Widget.Material3.Button.TextButton |
| Icon style | Widget.Material3.Button.TextButton.Icon |
| Full Width Buttons | Widget.Material3.Button.TextButton.Dialog.FullWidth |
Default style theme attribute: ?attr/borderlessButtonStyle
See the full list of styles and attrs.
</details>Buttons communicate actions that people can take.
They are typically placed throughout the UI, in places like:
They can also be placed within standard button groups.
Toggle buttons should be used for binary selections, such as Save or Favorite. When toggle buttons are pressed, they can change color, shape, and labels.
Toggle buttons should use an outlined icon when unselected, and a filled version of the icon when selected. If a filled version doesn’t exist, increase the weight instead.
By default, toggle buttons change from round to square when selected.
Before you can use Material buttons, you need to add a dependency to the Material components for Android library. For more information, go to the Getting started page.
Note: <Button> is auto-inflated as
<com.google.android.material.button.MaterialButton> via
MaterialComponentsViewInflater when using a Theme.Material3.* theme.
Elevated buttons are essentially outlined buttons with a shadow. To prevent shadow creep, only use them when absolutely necessary, such as when the button requires visual separation from a patterned background.
API and source code:
MaterialButton
The following example shows an elevated button with a text label.
In the layout:
<Button
style="?attr/materialButtonElevatedStyle"
android:id="@+id/elevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Elevated button"
/>
In code:
elevatedButton.setOnClickListener {
// Respond to button press
}
The following example shows an elevated button with an icon.
In the layout:
<Button
style="@style/Widget.Material3.Button.ElevatedButton.Icon"
...
app:icon="@drawable/ic_add_24dp"
/>
Filled button's contrasting surface color makes it the most prominent button after the FAB. It’s used for final or unblocking actions in a flow such as Save, Join now, or Confirm.
Note: The filled button is the default style if the style is not set.
API and source code:
MaterialButton
The following example shows a filled button with a text label and a filled container.
In the layout:
<Button
android:id="@+id/filledButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Filled button"
/>
Note: Since this is the default type, you don't need to specify a style tag
as long as you are using a Material components theme. If not, set the style to
@style/Widget.Material3.Button.
In code:
filledButton.setOnClickListener {
// Respond to button press
}
The following example shows a filled button with an icon.
In the layout:
<Button
style="@style/Widget.Material3.Button.Icon"
...
app:icon="@drawable/ic_add_24dp"
/>
Filled tonal buttons have a lighter background color and darker label color, making them less visually prominent than a regular filled button. They’re still used for final or unblocking actions in a flow, but may be better when these actions don’t require quite so much emphasis.
A tonal-style filled button can be used as an alternative middle-ground between filled and outlined buttons. They use secondary color mapping and are useful in contexts where a lower-priority button requires slightly more emphasis than an outline would give, such as Next in an onboarding flow.
API and source code:
MaterialButton
The following example shows a filled tonal button with a text label and a filled container.
In the layout:
<Button
style="?attr/materialButtonTonalStyle"
android:id="@+id/filledTonalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Filled tonal button"
/>
In code:
filledTonalButton.setOnClickListener {
// Respond to button press
}
The following example shows a filled tonal button with an icon.
In the layout:
<Button
style="@style/Widget.Material3.Button.TonalButton.Icon"
...
app:icon="@drawable/ic_add_24dp"
/>
Outlined buttons are for actions that need attention but aren’t the primary action, such as “See all” or “Add to cart.” This is also the button used to give someone the opportunity to change their mind or escape a flow.
Outlined buttons pair well with filled buttons to indicate a secondary, alternate action.
API and source code:
MaterialButton
The following example shows an outlined button with a text label and stroked container.
In the layout:
<Button
style="?attr/materialButtonOutlinedStyle"
android:id="@+id/outlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Outlined button"
/>
In code:
outlinedButton.setOnClickListener {
// Respond to button press
}
The following example shows an outlined button with an icon.
In the layout:
<Button
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
...
app:icon="@drawable/ic_add_24dp"
/>
Text buttons have less visual prominence, so should be used for low emphasis actions, such as when presenting multiple options.
API and source code:
MaterialButton
The following example shows a text button with a text label.
In the layout:
<Button
style="?attr/borderlessButtonStyle"
android:id="@+id/textButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text button"
/>
In code:
textButton.setOnClickListener {
// Respond to button press
}
The following example shows a text button with an icon.
In the layout:
<Button
style="@style/Widget.Material3.Button.TextButton.Icon"
...
app:icon="@drawable/ic_add_24dp"
/>
Buttons support content labeling for accessibility and are readable by most screen readers, such as TalkBack. Text rendered in buttons is automatically provided to accessibility services. Additional content labels are usually unnecessary.
For more information on content labels, go to the Android accessibility help guide.
Buttons support the customization of color, typography, and shape.
API and source code:
MaterialButton
The following example shows text, outlined and filled button types with Material theming.
Use theme attributes and styles in res/values/styles.xml to add the theme to
all buttons. This affects other components:
<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>
Use default style theme attributes, styles and theme overlays. This adds the theme to all buttons but does not affect other components:
<style name="Theme.App" parent="Theme.Material3.*">
...
<item name="borderlessButtonStyle">@style/Widget.App.Button.TextButton</item>
<item name="materialButtonOutlinedStyle">@style/Widget.App.Button.OutlinedButton</item>
<item name="materialButtonStyle">@style/Widget.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="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" 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="ThemeOverlay.App.Button.TextButton" parent="ThemeOverlay.Material3.Button.TextButton">
<item name="colorOnContainer">@color/shrine_pink_900</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="ShapeAppearance.App.Button" parent="">
<item name="cornerFamily">cut</item>
<item name="cornerSize">4dp</item>
</style>
Use one of the styles in the layout. That will affect only this button:
<Button
style="@style/Widget.App.Button"
...
/>
Optical centering means to offset the MaterialButton’s contents (icon and/or
label) when the shape is asymmetric. Before optical centering, we only provided
centering with horizontally asymmetrical shapes.
To turn on optical centering for a given button, use
setOpticalCenterEnabled(true). Optical centering is disabled by default. When
enabled, the shift amount of the icon and/or text is calculated as a value with
the fixed ratio to the difference between left corner size in dp and right
corner size in dp. The shift amount is applied to the padding start and padding
end.