37

I am using a CardView as element inside a RecyclerView. When doing so android automatically generates margins between the cardView and the screen and between different cardViews.

<android.support.v7.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/galleryCardBGColor"
app:cardCornerRadius="2dp" >

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

I followed the instructions in the link to integrate them into my project: using-recyclerview-and-cardview-in-eclipse-adt

I had been previously using a linearlayout for the list element :

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

This was working perfectly fine, with no margins whatsoever between the list elements. I have now just placed the linear layout inside the cardView which has resulted in extra margins.

The reason being that i want to provide exact margins to these elements, and any margins I supply now is being added over to this preexisting margins. I have tried supplying zero/negative paddings/margins to the cardView element but none of these work.

Any idea, I can remove these margins or otherwise know exactly how much margin is being added.

vj9
  • 1,546
  • 1
  • 11
  • 18

11 Answers11

47

did you check if it is margin or padding? (Dev Options / show layout bounds)

CardView adds padding in platforms pre-L to draw shadows. In L, unless you set useCompatPadding=true, there should not be any gap.

Adding negative margins (although it is ugly) should work. If it is not, please add some more code on how you are adding them and how you are setting up the RecyclerView.

sfmirtalebi
  • 370
  • 7
  • 16
yigit
  • 37,683
  • 13
  • 72
  • 58
  • 4
    It is a padding and yes I am testing on a pre-L device. Thanks for pointing me in the right direction : I found the following in the CardView documentation : 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. I can figure out the padding values from this(and subtract from what I want to provide). I don't have a L device for now, will update once I test on that. ps : -ve margins dont work. – vj9 Nov 20 '14 at 08:43
  • 3
    More precisely : card_view:cardUseCompatPadding="true" – Rémy DAVID Feb 02 '16 at 15:05
  • This worked for me: https://android.jlelse.eu/using-full-width-cards-to-maximize-content-f739cb863ce8 – Sagar Patel Nov 15 '17 at 11:03
45

It worked for me. Use:

 card_view:cardElevation="0dp"
 card_view:cardMaxElevation="0dp"
Shubham
  • 2,627
  • 3
  • 20
  • 36
  • 3
    This, in addition to setting `cardCornerRadius="1dp"` or some other arbitrary amount worked for me! Thanks, @Shubham I think setting the cardMaxElevation did the trick – w3bshark Jul 05 '15 at 15:32
  • 14
    Well I don't want to remove card elevation so your solution is a no go – Toochka Nov 18 '15 at 21:53
18

Just described in @yigit 's answer, the CardView will add a default padding to draw it's shadow before Android L. The padding size is described in CardView's doc.

I found the way to clear this padding (also to add padding for content) is to use CardView's contentPaddingLeft(/Right/Top/Bottom) attributes.

If you want to clear the default padding, you can set the contentPadding to minus value. If you want to add content padding, set the contentPadding to the value you want.

In my case, I use these code to clear the default padding:

card_view:contentPaddingLeft="-3dp"
card_view:contentPaddingRight="-3dp"
card_view:contentPaddingTop="-3dp"
card_view:contentPaddingBottom="-3dp"

I tried @Shubham 's answer, but an IllegalStateException is thrown in RadialGradient.java with message the "radius must be > 0".

Piasy
  • 989
  • 13
  • 35
18

Use this two tags below:

card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true"
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Omar Faroque Anik
  • 2,531
  • 1
  • 29
  • 42
5

add card_view:cardPreventCornerOverlap="false" to your card It works only if your Image has Rounded Corners

Logic
  • 2,230
  • 2
  • 24
  • 41
Shayan_Aryan
  • 2,002
  • 1
  • 29
  • 31
4

I know its late but i hope it will help someone

app:cardPreventCornerOverlap="false"

setting app:cardPreventCornerOverlap to false will do the trick :)

Zubair Rehman
  • 2,335
  • 2
  • 20
  • 25
  • This was actually my problem. Looks like the more corner radius you have, more padding is added to the content of the CardView. This makes sense as a default for avoiding cutting the content, but most of the times the content is actually not clipped. – Sotti Jan 28 '20 at 12:41
2

Well, seems there is a much easier way to do it, without guessing the padding and all:

card_view:cardPreventCornerOverlap="false"

or using java:

cardView.setPreventCornerOverlap(false)
Ani kukadiya
  • 174
  • 1
  • 10
1

The comment from @vj9 under the accepted question helped me to calculate the offsets. Sharing it here because it might help someone else:

public static int getVerticalCardViewOffset(Context context) {
    Resources res = context.getResources();
    int elevation = res.getDimensionPixelSize(R.dimen.cardview_default_elevation);
    int radius = res.getDimensionPixelSize(R.dimen.cardview_default_radius);
    return (int) (elevation * 1.5 + (1 - Math.cos(45)) * radius);
}

public static int getHorizontalCardViewOffset(Context context) {
    Resources res = context.getResources();
    int elevation = res.getDimensionPixelSize(R.dimen.cardview_default_elevation);
    int radius = res.getDimensionPixelSize(R.dimen.cardview_default_radius);
    return (int) (elevation + (1 - Math.cos(45)) * radius);
} 
Markus Rubey
  • 5,153
  • 2
  • 21
  • 17
  • Wouldn't it be better to get the real elevation from the card instead of assuming that it uses the default elevation? Sth like `float elevation = cardView.getCardElevation();` – Micky Apr 26 '16 at 07:55
  • Same for the radius: `float radius = cardView.getRadius();` – Micky Apr 26 '16 at 08:00
  • If you don't use the default cardview style, of course. Or change it to your own dimens. – Markus Rubey Apr 26 '16 at 08:04
0

use

android:adjustViewBounds="true"

on the view you want wrapped in the cardview

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Don Louis
  • 61
  • 1
  • 7
0

If you don't need the corner radius or elevation downlevel, consider using FrameLayout on pre-Lollipop.

<include layout="@layout/card_view_compat" />

layout/card_view_compat

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <include layout="@layout/content" />
    </FrameLayout>
</merge>

layout-v21/card_view_compat

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cardCornerRadius="3dp"
        app:cardElevation="4dp"
        >
        <include layout="@layout/content" />
    </android.support.v7.widget.CardView>
</merge>
owjsub
  • 231
  • 2
  • 4
-3

myCardView.setShadowPadding(0,0,0,0);

wildzic
  • 406
  • 5
  • 11