title: "Material chips" layout: detail section: components excerpt: "Chips are compact elements that represent an input, attribute, or action." iconId: chip path: /catalog/chips/ -->
Chips are compact elements that represent an input, attribute, or action.
Contents
Before you can use Material chips, you need to add a dependency to the Material Components for Android library. For more information, go to the Getting started page.
Chips allow users to enter information, make selections, filter content, or trigger actions. While buttons are expected to appear consistently and with familiar calls to action, chips should appear dynamically as a group of multiple interactive elements.
A Chip
can be added in a layout like so:
<com.google.android.material.chip.Chip
android:id="@+id/chip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text"/>
Changes to a chip can be observed like so:
chip.setOnClickListener {
// Responds to chip click
}
chip.setOnCloseIconClickListener {
// Responds to chip's close icon click if one is present
}
chip.setOnCheckedChangeListener { chip, isChecked ->
// Responds to chip checked/unchecked
}
Chips support content labeling for accessibility and are readable by most screen readers, such as TalkBack. Text rendered in chips is automatically provided to accessibility services. Additional content labels are usually unnecessary.
The Widget.MaterialComponents.Chip.*
styles use an
InsetDrawable
to extend the chip's touch target when necessary to meet Android's recommended
accessibility touch target size.
Developers can override a chip's minimum touch target size using
app:chipMinTouchTargetSize
. Developers can set whether the chip should extend
its bounds to meet the minimum touch target using app:ensureMinTouchTargetSize
(true by default).
Call setLayoutDirection(int)
with View.LAYOUT_DIRECTION_LOCALE
to ensure
that the chip's ancestor TextView
renders the text with proper paddings.
Without this, the initial rendering may look like the text has its padding set
according to LTR direction.
chip.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
Chips are mostly commonly used in groups. We recommend using ChipGroup
as it
is purpose-built to handle multi-chip layout and behavior patterns (as opposed
to a ViewGroup
such as RecyclerView
). A ChipGroup
contains a set of
Chip
s and manages their layout and multiple-exclusion scope, similarly to a
RadioGroup
.
A ChipGroup
rearranges chips across multiple rows by default.
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Chips can be declared here, or added dynamically. -->
</com.google.android.material.chip.ChipGroup>
A ChipGroup
can also constrain its chips to a single row using the
app:singleLine
attribute. Using a single row may necessitate wrapping the
ChipGroup
with a HorizontalScrollView
.
<HorizontalScrollView
... >
<com.google.android.material.chip.ChipGroup
...
app:singleLine="true">
<!-- Chips can be declared here, or added dynamically. -->
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
A ChipGroup
can insert spacing between chips in a row or between rows of chips
using the app:chipSpacing
attribute. Different horizontal and vertical spacing
can be set using the app:chipSpacingHorizontal
and app:chipSpacingVertical
attributes.
Note: The app:chipMinTouchTargetSize
will overrule vertical chip spacing
for lower amounts.
The following image shows a group of chips with
app:chipSpacingHorizontal="42dp"
.
The app:singleSelection
attribute can be set to true on a ChipGroup
in order
to toggle single-select and multi-select behavior of child chips.
The app:selectionRequired
attribute can be set to true on a ChipGroup
to
prevent all child chips from being deselected (i.e. at least one option should
be chosen).
Changes to child chip checked/unchecked state can be observed like so:
val checkedChipId = chipGroup.checkedChipId // Returns View.NO_ID if singleSelection = false
val checkedChipIds = chipGroup.checkedChipIds // Returns a list of the selected chips' IDs, if any
chipGroup.setOnCheckedChangeListener { group, checkedId ->
// Responds to child chip checked/unchecked
}
A standalone ChipDrawable
can be used in contexts that require a Drawable
.
The most obvious use case is in text fields that "chipify" contacts, commonly
found in communications apps.
To use a ChipDrawable
, first create a chip resource in res/xml
. Note that
you must use the <chip
tag in your resource file.
In res/xml/standalone_chip.xml
:
<chip
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:chipIcon="@drawable/ic_chip"
android:text="@string/text"/>
Entry Chip is the default Material style for standalone ChipDrawable
s, but you
can apply any of the other styles using the style
attribute. All the
attributes on Chip
can be applied to a ChipDrawable
resource.
A ChipDrawable can then be inflated from this resource like so:
val chipDrawable = ChipDrawable.createFromResource(context, R.xml.chip)
For example, consider an editable e-mail address field that converts addresses
to chips as they are typed and validated. We can combine ChipDrawable
with
spans to add a chip to an EditText
:
chip.setBounds(0, 0, chip.intrinsicWidth, chip.intrinsicHeight)
val span = ImageSpan(chip)
val text = editText.text!!
text.setSpan(span, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
There are four types of chips: 1. input (entry), 2. choice, 3. filter, 4. action
API and source code:
Chip
ChipGroup
ChipDrawable
Input chips (refered to as entry chips in Android) represent a complex piece of information in compact form, such as an entity (person, place, or thing) or text. They enable user input and verify that input by converting text into chips.
The following example shows three input chips.
In the layout:
<com.google.android.material.chip.ChipGroup
...>
<com.google.android.material.chip.Chip
android:id="@+id/chip_1"
style="@style/Widget.MaterialComponents.Chip.Entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_input_1"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Entry"
android:text="@string/text_input_2"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Entry"
android:text="@string/text_input_3"/>
</com.google.android.material.chip.ChipGroup>
Choice chips allow selection of a single chip from a set of options.
Choice chips clearly delineate and display options in a compact area. They are a good alternative to toggle buttons, radio buttons, and single select menus.
If you add choice chips to a dialog (which has 24dp elevation), disable the chips' elevation overlays to ensure that there is sufficient color contrast when the chips are checked.
<style name="Widget.MyApp.Chip.Choice" parent="Widget.MaterialComponents.Chip.Choice">
...
<item name="materialThemeOverlay">@style/ThemeOverlay.MyApp.Chip.Choice</item>
</style>
<!-- Disabling elevation overlays because when chip's default background/surface
composite are combined with elevation overlays in a highly elevated dialog,
the resulting color becomes too light and causes contrast
issues. -->
<style name="ThemeOverlay.MyApp.Chip.Choice" parent="">
<item name="elevationOverlayEnabled">false</item>
</style>
The following example shows four choice chips.
In the layout:
<com.google.android.material.chip.ChipGroup
...>
<com.google.android.material.chip.Chip
android:id="@+id/chip_1"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/text_choice_1"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_choice_2"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_choice_3"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_choice_4"/>
</com.google.android.material.chip.ChipGroup>
Filter chips use tags or descriptive words to filter content.
Filter chips clearly delineate and display options in a compact area. They are a good alternative to toggle buttons or checkboxes.
The following example shows six filter chips.
In the layout:
<com.google.android.material.chip.ChipGroup
...>
<com.google.android.material.chip.Chip
android:id="@+id/chip_1"
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/text_filter_1"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_filter_2"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:checked="true"
android:text="@string/text_filter_3"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_filter_4"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_filter_5"/>
<com.google.android.material.chip.Chip
...
style="@style/Widget.MaterialComponents.Chip.Choice"
android:text="@string/text_filter_6"/>
</com.google.android.material.chip.ChipGroup>
Action chips offer actions related to primary content. They should appear dynamically and contextually in a UI.
An alternative to action chips are buttons, which should appear persistently and consistently.
The following example shows four action chips.
In the layout:
<com.google.android.material.chip.ChipGroup
...>
<com.google.android.material.chip.Chip
android:id="@+id/chip_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIconTint="@color/icon_tint"
app:chipIcon="@drawable/favorite"
android:text="@string/text_action_1"/>
<com.google.android.material.chip.Chip
...
app:chipIconTint="@color/icon_tint"
app:chipIcon="@drawable/delete"
android:text="@string/text_action_2"/>
<com.google.android.material.chip.Chip
...
app:chipIconTint="@color/icon_tint"
app:chipIcon="@drawable/alarm"
android:text="@string/text_action_3"/>
<com.google.android.material.chip.Chip
...
app:chipIconTint="@color/icon_tint"
app:chipIcon="@drawable/location"
android:text="@string/text_action_4"/>
</com.google.android.material.chip.ChipGroup>
The following is an anatomy diagram of a chip:
- Container
- Thumbnail (optional)
- Text
- Remove icon (optional)
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Color | app:chipBackgroundColor |
setChipBackgroundColor setChipBackgroundColorResource getChipBackgroundColor |
?attr/colorOnSurface at 10% |
Ripple color | app:rippleColor |
setRippleColor setRippleColorResource getRippleColor |
?attr/colorOnSurface at 12% |
Stroke width | app:chipStrokeWidth |
setStrokeWidth setChipStrokeWidthResource getChipStrokeWidth |
0dp |
Stroke color | app:chipStrokeColor |
setStrokeColor setChipStrokeColorResource getChipStrokeColor |
?attr/colorOnSurface |
Min height | app:chipMinHeight |
setChipMinHeight setChipMinHeightResource getChipMinHeight |
32dp |
Padding | app:chipStartPadding app:chipEndPadding |
setChip*Padding setChip*PaddingResource getChip*Padding |
4dp (start)6dp (end) |
Shape | app:shapeAppearance shapeAppearanceOverlay |
setShapeAppearanceModel getShapeAppearanceModel |
?attr/shapeAppearanceSmallComponent with 50% cornerSize |
Min touch target | app:chipMinTouchTargetSize app:ensureMinTouchTargetSize |
ensureAccessibleTouchTarget setEnsureAccessibleTouchTarget shouldEnsureAccessibleTouchTarget |
48dp true |
Checkable | android:checkable |
setCheckable setCheckableResource isCheckable |
true (entry, filter, choice) |
Chip icon
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Icon | app:chipIcon |
setChipIconVisible isChipIconVisible |
null |
Visibility | app:chipIconVisible |
setChipIcon setChipIconResource getChipIcon |
true (action and entry) |
Color | app:chipIconTint |
setChipIconTint setChipIconTintResource getChipIconTint |
null |
Size | app:chipIconSize |
setChipIconSize setChipIconSizeResource getChipIconSize |
24dp |
Padding | app:iconStartPadding app:iconEndPadding |
setIcon*Padding setIcon*PaddingResource getIcon*Padding |
0dp |
Checked icon
If visible, the checked icon overlays the chip icon.
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Icon | app:checkedIcon |
setCheckedIconVisible isCheckedIconVisible |
@drawable/ic_mtrl_chip_checked_circle |
Visibility | app:checkedIconVisible |
setCheckedIcon setCheckedIconResource getCheckedIcon |
true (entry, filter, choice) |
Color | app:checkedIconTint |
setCheckedIconTint setCheckedIconTintResource getCheckedIconTint |
null |
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Text label | android:text |
setChipText setChipTextResource getChipText |
null |
Color | android:textColor |
setTextColor getTextColors |
?attr/colorOnSurface at 87% |
Typography | android:textAppearance |
setTextAppearance setTextAppearanceResource getTextAppearance |
?attr/textAppearanceBody2 |
Padding | app:textStartPadding app:textEndPadding |
setText*Padding setText*PaddingResource getText*Padding |
8dp (start)6dp (end) |
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Icon | app:closeIcon |
setCloseIcon setCloseIconResource getCloseIcon |
@drawable/ic_mtrl_chip_close_circle |
Visibility | app:closeIconVisible |
setCloseIconVisible isCloseIconVisible |
true for entry |
Color | app:closeIconTint |
setCloseIconTint setCloseIconTintResource getCloseIconTint |
?attr/colorOnSurface at 87% |
Size | app:closeIconSize |
setCloseIconSize setCloseIconSizeResource getCloseIconSize |
18dp |
Padding | app:closeIconStartPadding app:closeIconEndPadding |
setCloseIcon*Padding setCloseIcon*PaddingResource getCloseIcon*Padding |
2dp |
Content description | N/A | setCloseIconContentDescription getCloseIconContentDescription |
@string/mtrl_chip_close_icon_content_description |
Element | Attribute | Related method(s) | Default value |
---|---|---|---|
Layout | app:singleLine |
setSingleLine isSingleLine |
false |
Selection | app:singleSelection app:selectionRequired |
setSingleSelection* isSingleSelection* |
false false |
Spacing | app:chipSpacing app:chipSpacingHorizontal chipSpacingVertical |
setSpacing* setChipSpacing*Resource getSpacing* |
8dp |
Element | Style |
---|---|
Default style (action chip) | Widget.MaterialComponents.Chip.Action |
Input (entry) chip | Widget.MaterialComponents.Chip.Entry |
Choice chip | Widget.MaterialComponents.Chip.Choice |
Filter chip | Widget.MaterialComponents.Chip.Filter |
ChipGroup style |
Widget.MaterialComponents.ChipGroup |
Element | Theme attribute | Default style |
---|---|---|
Chip |
?attr/chipStyle |
Widget.MaterialComponents.Chip.Action |
ChipGroup |
?attr/chipGroupStyle |
Widget.MaterialComponents.ChipGroup |
ChipDrawable |
?attr/chipStandaloneStyle |
Widget.MaterialComponents.Chip.Entry |
See the full list of styles and attributes.
Chips support Material Theming and can be customized in terms of color, typography and shape.
API and source code:
Chip
ChipGroup
ChipDrawable
The following example shows chips with Material Theming.
Using theme attributes and styles in res/values/styles.xml
(themes all chips
and affects other components):
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="colorOnSurface">@color/shrine_pink_100</item>
<item name="textAppearanceBody2">@style/TextAppearance.App.Body2</item>
<item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
<item name="chipStyle">@style/Widget.App.Chip</item>
</style>
<style name="Widget.App.Chip" parent="Widget.MaterialComponents.Chip.Entry">
<item name="chipIconTint">@color/shrine_pink_900</item>
<item name="chipBackgroundColor">@color/white</item>
<item name="chipStrokeWidth">2dp</item>
<item name="chipStrokeColor">@color/stroke_tint</item>
<item name="checkedIconVisible">false</item>
<item name="shapeAppearanceOverlay">@null</item>
</style>
<style name="TextAppearance.App.Body2" parent="TextAppearance.MaterialComponents.Body2">
<item name="fontFamily">@font/rubik_regular</item>
<item name="android:fontFamily">@font/rubik_regular</item>
</style>
<style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerFamily">cut</item>
<item name="cornerSize">4dp</item>
</style>
in color/stroke_tint.xml
:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorOnSurface" android:state_checked="true"/>
<item android:color="@color/shrine_pink_100"/>
</selector>
or using a default style theme attribute, styles and a theme overlay (themes all chips but does not affect other components):
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="chipStyle">@style/Widget.App.Chip</item>
</style>
<style name="Widget.App.Chip" parent="Widget.MaterialComponents.Chip.Entry">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Chip</item>
<item name="android:textAppearance">@style/TextAppearance.App.Body2</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.SmallComponent</item>
...
</style>
<style name="ThemeOverlay.App.Chip" parent="">
<item name="colorOnSurface">@color/shrine_pink_900</item>
</style>
or using the style in the layout (affects only this specific chips):
<com.google.android.material.chip.Chip
...
style="@style/Widget.App.Chip." />