Setting margin programmatically to CardView
Asked Answered
S

4

21

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>
Synder answered 28/5, 2017 at 3:15 Comment(4)
Could you show me the cardview in your xml code?Entropy
@red_allocator i've updated my question to show the CardView in xmlOrfinger
Who is the direct parent of your CardView?Korman
@Korman LinearLayout. I've updated my question so you can see my layoutOrfinger
K
47

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();
Korman answered 28/5, 2017 at 4:22 Comment(2)
This is not true for the *LayoutParams classes that are subclasses of ViewGroup#LayoutParamsArrest
Thank you for the solution, saved much of my time!Collection
S
10

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
Sisco answered 26/5, 2018 at 12:52 Comment(0)
E
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);
Entropy answered 28/5, 2017 at 4:4 Comment(6)
I don't want to set padding. I want to set margin. It is completely differentOrfinger
You mean that LinearLayout have to move for margine?Entropy
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.Orfinger
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 meOrfinger
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 somethingOrfinger
cardview parent is LinearLayout set padding Parent LInearLayoutEntropy
A
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()
Acrostic answered 15/6, 2022 at 5:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.