1

I am trying to create some views programmatically to match a mock-up that I have made in an XML layout, but they are displaying differently despite seemingly having the same properties.

enter image description here

The card on the left is created using the XML below, the one on the right is created using code. The correct layout is the one on the left, where is my code wrong?

XML (left image)

<LinearLayout
    android:layout_width="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/cardViewContainer"
    android:layout_height="200dp">
    <android.support.v7.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/testCard">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:minHeight="200dp"
            android:minWidth="200dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TEST TITLE"
                android:layout_weight="1"
                android:layout_gravity="bottom"
                android:gravity="center"
                android:layout_margin="5px" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

Code (right image)

var layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);

int cardMinDims = (int)(200 * scale + 0.5f);

TextView title = new TextView(this);
title.Text = "TEST TITLE";
title.Gravity = GravityFlags.Center;
var title_layoutParams = layoutParams;
title_layoutParams.Weight = 1;
title_layoutParams.Gravity = GravityFlags.Bottom;
title_layoutParams.SetMargins(5, 5, 5, 5);

LinearLayout layout = new LinearLayout(this);
layout.SetMinimumHeight(cardMinDims);
layout.SetMinimumWidth(cardMinDims);
layout.Orientation = Orientation.Vertical;
layout.AddView(title,title_layoutParams);

CardView card = new CardView(this);
card.AddView(layout, layoutParams);

LinearLayout cardViewContainer = FindViewById<LinearLayout>(Resource.Id.cardViewContainer);
cardViewContainer.AddView(card,layoutParams);
tallpaul
  • 1,220
  • 2
  • 13
  • 35

1 Answers1

0

In your code you are re-using your LayoutParams:-

i.e.

var layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);

var title_layoutParams = layoutParams;

So now there is a reference from title_layoutParams object pointing to the same object reference of layoutParams.

Your then using the same layoutParams later on.

As these are object references any changes you make will be applied to all other variables as they are pointing to the same object.

I've re-created the demo, in code, below which is practically the same as your axml with only a couple adjustments for the layout_width and layout_height for the CardView and the inner LinearLayout to get this working as expected:-

I've ommitted any scaling from the demo below:-

Example:-

        LinearLayout objLinearLayout_CardViewContainer = new LinearLayout(this);
        objLinearLayout_CardViewContainer.Orientation = Orientation.Horizontal;
        objLinearLayout_CardViewContainer.LayoutParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, 400);

        Android.Support.V7.Widget.CardView objCardView = new CardView(this);
        objLinearLayout_CardViewContainer.AddView(objCardView, LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.MatchParent);

        LinearLayout objCardViewLinearLayout = new LinearLayout(this);
        objCardViewLinearLayout.SetMinimumWidth(400);
        objCardViewLinearLayout.SetMinimumHeight(400);
        objCardView.AddView(objCardViewLinearLayout, CardView.LayoutParams.MatchParent, CardView.LayoutParams.MatchParent);

        TextView objTextView = new TextView(this);
        objTextView.Text = "TEST TITLE";
        objTextView.SetTextColor(Color.Red);
        objTextView.Gravity = GravityFlags.Center;

        LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WrapContent, LinearLayout.LayoutParams.WrapContent);
        objLayoutParams.Weight = 1;
        objLayoutParams.Gravity = GravityFlags.Bottom;
        objLayoutParams.SetMargins(5, 5, 5, 5);

        objCardViewLinearLayout.AddView(objTextView, objLayoutParams);

You will then get an output similar to:-

enter image description here

Pete
  • 4,746
  • 2
  • 15
  • 21