Cards contain content and actions about a single subject. There are three variants of cards: elevated, filled, and outlined.

Before you can use a Material card, you need to add a dependency to the Material Components for Android library. For more information, go to the Getting started page.
Cards support checking and dragging, but those behaviors are not implemented by default.
A card has a container and an optional thumbnail, header text, secondary text, media, supporting text, buttons and icons.

Note: All the optional elements of a card’s content (with the exception of the checked icon) are implemented through the use of other views/components, as shown in the card examples section.
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:cardBackgroundColor |
setCardBackgroundColorgetCardBackgroundColor |
?attr/colorSurface (outlined style)</br>?attr/colorSurfaceContainerHighest (filled style)</br>?attr/colorSurfaceContainerLow (elevated style) |
| Foreground color | app:cardForegroundColor |
setCardForegroundColorgetCardForegroundColor |
@android:color/transparent (see all states) |
| Stroke color | app:strokeColor |
setStrokeColorgetStrokeColorgetStrokeColorStateList |
?attr/colorOutline (unchecked)?attr/colorSecondary (checked) |
| Stroke width | app:strokeWidth |
setStrokeWidthgetStrokeWidth |
1dp (outlined style)0dp (elevated or filled style) |
| Shape | app:shapeAppearance |
setShapeAppearanceModelgetShapeAppearanceModel |
?attr/shapeAppearanceCornerMedium |
| Elevation | app:cardElevation |
setCardElevationsetCardMaxElevation |
0dp (outlined or filled style)1dp (elevated style) |
| Ripple color | app:rippleColor |
setRippleColorsetRippleColorResourcegetRippleColor |
?attr/colorOnSurfaceVariant at 20% opacity (see all states) |
Note: We recommend that cards on mobile have 8dp margins.
android:layout_margin will NOT
work in default styles (for example materialCardViewStyle) so either set this
attr directly on a MaterialCardView in the layout or add it to a style that is
applied in the layout with style="@style/....
Note: Without an app:strokeColor, the card will not render a stroked
border, regardless of the app:strokeWidth value.
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Icon | checkedIcon |
setCheckedIconsetCheckedIconResourcegetCheckedIcon |
@drawable/ic_mtrl_checked_circle.xml |
| Color | checkedIconTint |
setCheckedIconTintgetCheckedIconTint |
?attr/colorOutline (unchecked)?attr/colorSecondary (checked) |
| Checkable | android:checkable |
setCheckableisCheckable |
false |
| Size | checkedIconSize |
setCheckedIconSizesetCheckedIconSizeResourcegetCheckedIconSize |
24dp |
| Margin | checkedIconMargin |
setCheckedIconMarginsetCheckedIconMarginResourcegetCheckedIconMargin |
8dp |
| Gravity | checkedIconGravity |
setCheckedIconGravitygetCheckedIconGravity |
TOP_END |
Cards can have the following states:
| State | Description | Related method(s) |
|---|---|---|
| Default | Card is not checked and not dragged | N/A |
Checked (android:state_checked) |
true if a card is checked |
setCheckedsetOnCheckedChangeListenerisChecked |
Dragged (app:state_dragged) |
true when a card is being dragged |
setDraggedisDragged |
| Element | Style |
|---|---|
| Default style | Widget.Material3.CardView.Outlined |
Default style theme attribute: ?attr/materialCardViewStyle
Additional style theme attributes: ?attr/materialCardViewOutlinedStyle,
?attr/materialCardViewFilledStyle, ?attr/materialCardViewElevatedStyle
See the full list of styles and attributes.
```xml
In the layout:
```xml
<com.google.android.material.card.MaterialCardView
...
style="?attr/materialCardViewFilledStyle">
...
</com.google.android.material.card.MaterialCardView>
```
In the layout:
```xml
<com.google.android.material.card.MaterialCardView
...
style="?attr/materialCardViewElevatedStyle">
...
</com.google.android.material.card.MaterialCardView>
```
When a card is checked, it will show a checked icon and change its foreground
color. There is no default behavior for enabling/disabling the checked state. An
example of how to do it in response to a long click is shown below.
In the layout:
```xml
<com.google.android.material.card.MaterialCardView
...
android:clickable="true"
android:focusable="true"
android:checkable="true">
...
</com.google.android.material.card.MaterialCardView>
```
In code:
```kt
card.setOnLongClickListener {
card.setChecked(!card.isChecked)
true
}
```
Cards have an `app:state_dragged` with foreground and elevation changes to
convey motion. We recommend using
[`ViewDragHelper`](https://developer.android.com/reference/androidx/customview/widget/ViewDragHelper)
to set the dragged state:
```kt
private inner class ViewDragHelperCallback : ViewDragHelper.Callback() {
override fun onViewCaptured(capturedChild: View, activePointerId: Int) {
if (capturedChild is MaterialCardView) {
(view as MaterialCardView).setDragged(true)
}
}
override fun onViewReleased(releaseChild: View, xVel: Float, yVel: Float) {
if (releaseChild is MaterialCardView) {
(view as MaterialCardView).setDragged(false)
}
}
}
```
Alternatively, the
[Material Catalog](https://github.com/material-components/material-components-android/tree/master/catalog/java/io/material/catalog/card)
has an implementation example that you can copy, which uses a custom class
called
[`DraggableCoordinatorLayout`](https://github.com/material-components/material-components-android/tree/master/catalog/java/io/material/catalog/draggable/DraggableCoordinatorLayout.java).
It is used as the parent container in the layout:
In the layout:
```xml
<io.material.catalog.draggable.DraggableCoordinatorLayout
android:id="@+id/parentContainer"
...>
<com.google.android.material.card.MaterialCardView
...>
...
</com.google.android.material.card.MaterialCardView>
</io.material.catalog.draggable.DraggableCoordinatorLayout>
```
In code:
```kt
parentContainer.addDraggableChild(card)
parentContainer.setViewDragListener(object : DraggableCoordinatorLayout.ViewDragListener {
override fun onViewCaptured(view: View, pointerId: Int) {
card.isDragged = true
}
override fun onViewReleased(view: View, vX: Float, vY: Float) {
card.isDragged = false
}
})
```
Finally, make sure the behavior is accessible by setting an
[`AccessibilityDelegate`](https://developer.android.com/reference/android/view/View.AccessibilityDelegate)
on the card. The code below demonstrates how to allow the user to move the card
to two different positions on the screen.
```kt
private val cardDelegate = object : AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
super.onInitializeAccessibilityNodeInfo(host, info)
val layoutParams = card!!.layoutParams as CoordinatorLayout.LayoutParams
val gravity = layoutParams.gravity
val isOnTop = gravity and Gravity.TOP == Gravity.TOP
val isOnBottom = gravity and Gravity.BOTTOM == Gravity.BOTTOM
if (!isOnTop) {
info.addAction(AccessibilityAction(R.id.move_card_top_action, getString(R.string.card_action_move_top)))
}
if (!isOnBottom) {
info.addAction(AccessibilityAction(R.id.move_card_bottom_action, getString(R.string.card_action_move_bottom)))
}
}
override fun performAccessibilityAction(host: View, action: Int, arguments: Bundle): Boolean {
val gravity: Int
if (action == R.id.move_card_top_action) {
gravity = Gravity.TOP
} else if (action == R.id.move_card_bottom_action) {
gravity = Gravity.BOTTOM
} else {
return super.performAccessibilityAction(host, action, arguments)
}
val layoutParams = card!!.layoutParams as CoordinatorLayout.LayoutParams
if (layoutParams.gravity != gravity) {
layoutParams.gravity = gravity
card!!.requestLayout()
}
return true
}
}
```
**Note:** Cards also support a swipe-to-dismiss behavior through the use of
['SwipeDismissBehavior'](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/behavior/SwipeDismissBehavior.java).
You can see an example
[here](https://github.com/material-components/material-components-android/tree/master/catalog/java/io/material/catalog/card/CardSwipeDismissFragment.java).