androidandroid-layoutandroid-cardviewlayoutparamsandroid-layoutparams

Setting margin programmatically to CardView


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>

Solution

  • 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();