# Cards [Cards](https://material.io/components/cards/) contain content and actions about a single subject. !["Cards on a screen"](assets/cards/cards_hero.png) ## Contents * [Using cards](#using-cards) * [Card](#card) * [Theming](#theming-cards) ## Using cards 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](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md) page. Cards support [checking](#making-a-card-checkable) and [dragging](#making-a-card-draggable), but those behaviors are not implemented by default. ### Making cards accessible The contents within a card should follow their own accessibility guidelines, such as images having content descriptions set on them. If you have a draggable card, you should set an [`AccessibilityDelegate`](https://developer.android.com/reference/android/view/View.AccessibilityDelegate) on it, so that the behavior can be accessible via screen readers such as TalkBack. See the [draggable card section](#making-a-card-draggable) section below for more info. ### Making a card checkable ![Elevated card with a checked button and a light purple overlay; secondary title and Action 1 and Action 2 buttons](assets/cards/cards_checked.png) 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 ... ``` In code: ```kt card.setOnLongClickListener { card.setChecked(!card.isChecked) true } ``` ### Making a card draggable ![Elevated card with a light grey overlay; secondary title and Action 1 and Action 2 buttons](assets/cards/cards_dragged.png) Cards have an `app:state_dragged` that has 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 uses a custom class called [`DraggableCoordinatorLayout`](https://github.com/material-components/material-components-android/tree/master/catalog/java/io/material/catalog/draggable/DraggableCoordinatorLayout.java) that you can copy, which is used as the parent container in the layout: In the layout: ```xml ... ``` 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 to make the behavior is accessible by setting an [`AccessibilityDelegate`](https://developer.android.com/reference/android/view/View.AccessibilityDelegate) on the card. The following shows an example of allowing 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)._ ## Card On mobile, a [card’s](https://material.io/components/cards/#specs) default elevation is `1dp`, with a raised dragged elevation of `8dp`. ![Elevated card with a secondary title and Action 1 and Action 2 buttons in purple](assets/cards/cards_basic.png) ### Card examples API and source code: * `MaterialCardView` * [Class definition](https://developer.android.com/reference/com/google/android/material/card/MaterialCardView) * [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/card/MaterialCardView.java) _**Note:** 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 `Widget.MaterialComponents.CardView`._ #### Elevated card The following example shows an elevated card. !["Elevated card with a title, a secondary title, text, and Action 1 and Action 2 buttons in purple"](assets/cards/cards_elevated.png) ```xml ``` #### Outlined card The following example shows an outlined card. !["Outlined card with a title, a secondary title, text, and Action 1 and Action 2 buttons in purple"](assets/cards/cards_outlined.png) In the layout: ```xml ... ``` In the stroke color (`stroke_color.xml`): ```xml ``` ### Anatomy and key properties A card has a container and an optional thumbnail, header text, secondary text, media, supporting text, buttons and icons. ![card anatomy diagram](assets/cards/card-anatomy.png) 1. Container 2. Thumbnail 3. Header text 4. Secondary text 5. Media 6. Supporting text 7. Buttons 8. Icons 9. Checked icon (not shown) _**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](#card-examples) section._ #### Container attributes   | Attribute | Related method(s) | Default value -------------------- | ------------------------- | ------------------------------------------------------------------- | ------------- **Color** | `app:cardBackgroundColor` | `setCardBackgroundColor`
`getCardBackgroundColor` | `?attr/colorSurface` **Foreground color** | `app:cardForegroundColor` | `setCardForegroundColor`
`getCardForegroundColor` | `@android:color/transparent` (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/card/res/color/mtrl_card_view_foreground.xml)) **Stroke color** | `app:strokeColor` | `setStrokeColor`
`getStrokeColor`
`getStrokeColorStateList` | `null` **Stroke width** | `app:strokeWidth` | `setStrokeWidth`
`getStrokeWidth` | `0dp` **Shape** | `app:shapeAppearance` | `setShapeAppearanceModel`
`getShapeAppearanceModel` | `?attr/shapeAppearanceMediumComponent` **Elevation** | `app:cardElevation` | `setCardElevation`
`setCardMaxElevation` | `1dp` **Ripple color** | `app:rippleColor` | `setRippleColor`
`setRippleColorResource`
`getRippleColor` | `?attr/colorOnSurface` at 20% opacity (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/card/res/color/mtrl_card_view_ripple.xml)) _**Note:** We recommend that cards on mobile have `8dp` margins. `android:layout_margin` will [**NOT**](https://stackoverflow.com/a/13365288) work in default styles (eg. `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._ #### Checked icon attributes   | Attribute | Related method(s) | Default value ------------- | ------------------- | ------------------------------------------------------------------------------------ | ------------- **Icon** | `checkedIcon` | `setCheckedIcon`
`setCheckedIconResource`
`getCheckedIcon` | [`@drawable/ic_mtrl_checked_circle.xml`](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/resources/res/drawable/ic_mtrl_checked_circle.xml) **Color** | `checkedIconTint` | `setCheckedIconTint`
`getCheckedIconTint` | `?attr/colorPrimary` **Checkable** | `android:checkable` | `setCheckable`
`isCheckable` | `false` **Size** | `checkedIconSize` | `setCheckedIconSize`
`setCheckedIconSizeResource`
`getCheckedIconSize` | `24dp` **Margin** | `checkedIconMargin` | `setCheckedIconMargin`
`setCheckedIconMarginResource`
`getCheckedIconMargin` | `8dp` #### States 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 | `setChecked`
`setOnCheckedChangeListener`
`isChecked` **Dragged** (`app:state_dragged`) | `true` when a card is being dragged | `setDragged`
`isDragged` #### Styles   | Style ----------------- | ------------------------------------ **Default style** | `Widget.MaterialComponents.CardView` Default style theme attribute: `?attr/materialCardViewStyle` See the full list of [styles](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/card/res/values/styles.xml) and [attributes](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/card/res/values/attrs.xml). ## Theming cards A card supports [Material Theming](https://material.io/components/cards/#theming) and can be customized in terms of color, typography and shape. ### Card theming example API and source code * `MaterialCardView` * [Class definition](https://developer.android.com/reference/com/google/android/material/card/MaterialCardView) * [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/card/MaterialCardView.java) The following example shows a card with Material Theming. ![Card theming example in Shrine theme](assets/cards/cards_theming.png) #### Implementing card theming Using theme attributes and a style in `res/values/styles.xml` (themes all cards and affects other components): ```xml ``` or using a default style theme attribute, styles and a theme overlay (themes all cards but does not affect other components): ```xml ``` or using the style in the layout (affects only this specific card): ```xml ``` In order to optimize shape theming, some (optional) adjustments need to be made to the card layout to incorporate [ShapeableImageView](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/imageview/ShapeableImageView.java). In the layout: ```xml ... ``` In `res/values/styles.xml`: ```xml ``` _**Note:** In order to theme card contents (text, buttons, etc.), the relevant styles/attributes for these components will need to be included. For more information, see the article on [buttons](https://material.io/develop/android/components/buttons/)._