Setting margin programmatically to CardView

ᴛʜᴇᴘᴀᴛᴇʟ picture ᴛʜᴇᴘᴀᴛᴇʟ · May 28, 2017 · Viewed 13.2k times · Source

I have a CardView in my XML layout and I need to set margins to it programmatically (This is because I don't need margin at all times. Based on few conditions, I either set or remove the margin).

Here's how I did it:

CardView.LayoutParams layoutParams = (CardView.LayoutParams) myCardView.getLayoutParams();
layoutParams.setMargins(0, 0, SystemHelper.dpToPx(2), 0);
myCardView.setLayoutParams(layoutParams);

This worked fine. It put 2dp margin at the bottom of my CardView. However, I get this in my logcat:

java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams

So I changed CardView.LayoutParams to FrameLayout.LayoutParams, like this:

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) myCardView.getLayoutParams();
layoutParams.setMargins(0, 0, SystemHelper.dpToPx(2), 0);
myCardView.setLayoutParams(layoutParams);

And yet again, it works but I get the same error as above.

So I modified it one more time to use LinearLayout.LayoutParams.

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) myCardView.getLayoutParams();
layoutParams.setMargins(0, 0, SystemHelper.dpToPx(2), 0);
myCardView.setLayoutParams(layoutParams);

When I do this, I do NOT get the error however it does not set any margin.

Should I just ignore the error? It just doesn't seem right.

EDIT:

Here's my CardView in XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:background="@android:color/white"
    android:minHeight="@dimen/item_min_height"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:id="@+id/cardViewAppointmentWeek"
        app:cardElevation="2dp"
        android:layout_marginBottom="2dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:orientation="horizontal"
            android:background="?android:attr/selectableItemBackground"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            ...

        </LinearLayout>

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

</LinearLayout>

Answer

azizbekian picture azizbekian · May 28, 2017

In your case you are not specifically interested who is the parent of your CardView, because the only thing you want to change is the margin. All of the *LayoutParams classes are direct/indirect children of MarginLayoutParams, which means you can easily cast to MarginLayoutParams and perform change on that object:

ViewGroup.MarginLayoutParams layoutParams =
        (ViewGroup.MarginLayoutParams) myCardView.getLayoutParams();
layoutParams.setMargins(0, 0, SystemHelper.dpToPx(2), 0);
myCardView.requestLayout();