19

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>
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73

4 Answers4

46

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();
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73
azizbekian
  • 60,783
  • 13
  • 169
  • 249
8

1) Set the Cardview Parameters for it to be displayed programtically

Setting Carview Parameters

CardView cardView = new CardView(context);
LinearLayout.LayoutParams cardViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);  
cardView.setLayoutParams(cardViewParams)

2) Set the Parameters for displaying the Margins around the cardview

Setting Params for Cardview Margins

ViewGroup.MarginLayoutParams cardViewMarginParams = (ViewGroup.MarginLayoutParams) cardView.getLayoutParams(); 
cardViewMarginParams.setMargins(0, 30, 0, 30);
cardView.requestLayout();  //Dont forget this line
Kishan Viramgama
  • 893
  • 1
  • 11
  • 23
fritz-playmaker
  • 693
  • 1
  • 10
  • 15
0
  1. Set Linearlayout id your CardView child
  2. Find linearlayout from findViewById.
  3. Set LayoutParams
LinearLayout linearLayout = (LinearLayout)myCardView.findViewById(R.id.linearlayoutid);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(30, 20, 30, 0);
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73
redAllocator
  • 725
  • 6
  • 12
  • 1
    I don't want to set padding. I want to set margin. It is completely different – ᴛʜᴇᴘᴀᴛᴇʟ May 28 '17 at 04:05
  • You mean that LinearLayout have to move for margine? – redAllocator May 28 '17 at 04:11
  • No. I don't want to do anything with my `LinearLayout`. Please read my original question. I want to set `2dp` margin on my `CardView` programmatically. – ᴛʜᴇᴘᴀᴛᴇʟ May 28 '17 at 04:12
  • You are setting margin to `LinearLayout`. I need to set it on `CardView` because `CardView` has a field called `cardElevation`. If `cardElevation` is set to `2dp`, shadow is not visible until you have a `2dp` margin at the bottom. So setting margin on `LinearLayout` doesn't help me – ᴛʜᴇᴘᴀᴛᴇʟ May 28 '17 at 04:20
  • Are you serious? Padding is counted within the view's width and height and applied inside. Margin is counted outside the view's width and height and applied outside. Understand the question before you try to answer and tell someone else to understand something – ᴛʜᴇᴘᴀᴛᴇʟ May 28 '17 at 04:24
  • cardview parent is LinearLayout set padding Parent LInearLayout – redAllocator May 28 '17 at 04:28
0

Kotlin In kotlin layout margin set from code is tricky.

val cardView = CardView(context)
(cardView.layoutParams as? ViewGroup.MarginLayoutParams)?.leftMargin = 2
(cardView.layoutParams as? ViewGroup.MarginLayoutParams)?.bottomMargin = 2
cardView.requestLayout()
Jamil Hasnine Tamim
  • 4,389
  • 27
  • 43