How to set the padding for CardView widget in Android L

AndroidPaddingAndroid 5.0-LollipopAndroid Cardview

Android Problem Overview


I'm using android:paddingLeft and android:paddingTop to set the padding for the new CardView widget but it doesn't work.

I can set the margin for all the controls inside the CardView as a workaround but that's a pain if there are too many controls.

How to set padding for the new cardview widget?

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:paddingLeft="20dp"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="20dp"
    android:paddingBottom="@dimen/activity_vertical_margin"
    card_view:cardCornerRadius="2dp">

    <TextView
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</android.support.v7.widget.CardView>

Android Solutions


Solution 1 - Android

CardView should handle this using the contentPadding attributes it comes with:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    card_view:cardCornerRadius="2dp"
    card_view:contentPaddingLeft="20dp"
    card_view:contentPaddingRight="@dimen/activity_horizontal_margin"
    card_view:contentPaddingTop="20dp"
    card_view:contentPaddingBottom="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</android.support.v7.widget.CardView>

Solution 2 - Android

CardView prior to L-preview uses RoundRectDrawableWithShadow to draw its background, which overrides Drawable.getPadding() to add shadow padding. The view background gets set via code after inflation, which overrides any padding specified in XML.

You have two options:

  1. Set padding at run time using View.setPadding() and be careful to adjust for the shadows (but only prior to L-preview!).
  2. Place everything inside a layout that specifies padding.

The latter option is safest.

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    card_view:cardCornerRadius="2dp">

    <FrameLayout
        android:paddingLeft="20dp"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="20dp"
        android:paddingBottom="@dimen/activity_vertical_margin">

        <TextView
            android:id="@+id/info_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World!"/>
    </FrameLayout>
</android.support.v7.widget.CardView>

Solution 3 - Android

If you want to use CardView padding on pre-L devices, and have it look the same on Lollipop+ devices, then you will need to use setUseCompatPadding(true), or the XML variant cardUseCompatPadding="true".

This is because "CardView adds additional padding to draw shadows on platforms before L."[1] So, the default implementation has the different API versions looking different and views may not line up properly. So, the easiest way to fix that issue is the ways stated above, or use margins instead.

Example Code
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_context"
    card_view:cardUseCompatPadding="true"
    card_view:contentPadding="8dp"
    card_view:cardCornerRadius="4dp" >

    ...

</android.support.v7.widget.CardView>
Sources

[1] CardView.setUseCompatPadding(boolean)

[2] android.support.v7.cardview:cardUseCompatPadding

Solution 4 - Android

This is what worked for me - putting every item in a frame layout

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
 android:layout_marginBottom="-4dp">

   <android.support.v7.widget.CardView   
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
       
            android:background="@color/white_three"
            android:orientation="vertical"
            card_view:cardCornerRadius="2dp"
            card_view:cardElevation="@dimen/card_elevation"
            card_view:cardMaxElevation="0dp"
            card_view:cardPreventCornerOverlap="false"
            card_view:cardUseCompatPadding="true"
   </android.support.v7.widget.CardView>

Double check that card_view is "http://schemas.android.com/apk/res-auto" and not tools, and also set negative margins on the frame view to maintain shadows - works fine.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnomongoView Question on Stackoverflow
Solution 1 - AndroidyarianView Answer on Stackoverflow
Solution 2 - AndroidalanvView Answer on Stackoverflow
Solution 3 - AndroidAnonsageView Answer on Stackoverflow
Solution 4 - AndroidHannahCarneyView Answer on Stackoverflow