82

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>
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
nomongo
  • 3,435
  • 7
  • 30
  • 33

5 Answers5

216

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>
yarian
  • 5,922
  • 3
  • 34
  • 48
  • 1
    Since it makes no sense to define "padding" attribute on CardView, why can't the cardview copy the padding attribute into it's own internal contentPadding? We are just supposed to remember/know that CardView has something called contentPadding we should use instead of padding? @MichelJung – Greg Ennis Mar 01 '15 at 04:12
  • 1
    @GregEnnis Because it does make sense to define padding for CardView. In fact, the Android system does just that: `Before L, CardView adds padding to its content and draws shadows to that area. This padding amount is equal to maxCardElevation + (1 - cos45) * cornerRadius on the sides and maxCardElevation * 1.5 + (1 - cos45) * cornerRadius on top and bottom.` It's a matter of differentiating padding that gets applied to the card background from the internal content padding. – yarian Mar 02 '15 at 21:47
  • 6
    @yarian that didn't answer my question at all. Actually it just made things worse. Not sure how someone new to Android development could possible be expected to sort this out – Greg Ennis Mar 02 '15 at 22:27
  • 1
    @yarian any idea how `card_view:contentPadding` could be specified within a custom style (`styles.xml`)? – Gautam Nov 25 '15 at 15:56
  • This worked perfectly for me on a phone running Android 7.1. However, it had no effect on my other phone that runs Android 4.1.2. – Sam Apr 02 '17 at 00:45
  • @Gautam `contentPaddingX` worked for me (where X can be Left, Top, Bottom, Right, or empty). For example: `20dp` – O-9 Jun 10 '19 at 11:54
74

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>
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
alanv
  • 23,966
  • 4
  • 93
  • 80
37

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

Anonsage
  • 8,030
  • 5
  • 48
  • 51
1

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.

HannahCarney
  • 3,441
  • 2
  • 26
  • 32
0

Just add below two lines

<androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="24dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="24dp"
            android:layout_marginLeft="16dp"
            app:cardUseCompatPadding="true" // add this line
            app:contentPadding="16dp" // add this line`enter code here`
            app:cardCornerRadius="8dp"
           >
        </androidx.cardview.widget.CardView>

that's all... enjoy your coding...

Mahendren Mahisha
  • 1,072
  • 11
  • 9