Creating LinearLayout Programmatically/Dynamically with Multiple Views
Asked Answered
U

4

44

I have a hierarchy that is like this:

  • LinearLayout(horizontal)
    • ImageView
    • LinearLayout(vertical)
      • TextView
      • TextView
      • TextView
      • TextView

I want to be able to add the hierarchy above through iteration as long as there is data that could be obtained from the database(using Parse)

I have tried putting up the ImageView and LinearLayout under the parent LinearLayout but it doesn't seem to work. Here is my code in MainActivity.Java:

LinearLayout LL_Outer = (LinearLayout) findViewById(R.id.new_linearLayoutOuter);
LL_Outer.setOrientation(LinearLayout.VERTICAL); // set orientation
LL_Outer.setBackgroundColor(color.white); // set background
// set Layout_Width and Layout_Height
LinearLayout.LayoutParams layoutForOuter = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
LL_Outer.setLayoutParams(layoutForOuter);


LinearLayout LL_Inner = (LinearLayout) findViewById(R.id.new_linearLayoutInner);
LL_Inner.setOrientation(LinearLayout.HORIZONTAL);
LL_Inner.setBackgroundColor(color.white);
LinearLayout.LayoutParams layoutForInner = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
LL_Inner.setLayoutParams(layoutForInner);

//LL_Outer.addView(LL_Inner);

ImageView IV = (ImageView) findViewById(R.id.new_imageViewPP);
//IV.getLayoutParams().height = 55;
//IV.getLayoutParams().width = 55;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(14, 12, 0, 0);
params.height = 55;
params.weight = 55;
IV.setBackgroundColor(color.black);
IV.setLayoutParams(params);

LL_Inner.addView(IV);
LL_Outer.addView(LL_Inner);

I don't know where I went wrong as my code did not prompt any error. Please help.

EDIT: I have edited the Orientations accordingly and when I run the app, it stops working. And prompts an error in LogCat saying "The specified child already has a parent. You must call removeView() on the child's parent first.

Here's my XML:

<LinearLayout
    android:id="@+id/new_linearLayoutOuter"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="horizontal" >

    <ImageView
            android:id="@+id/new_imageViewPP"
            android:layout_width="55dp"
            android:layout_height="55dp"
            android:layout_marginLeft="14dp"
            android:layout_marginTop="12dp"
            android:background="@color/black"
            android:contentDescription="@string/pp" />

    <LinearLayout
        android:id="@+id/new_linearLayoutInner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="vertical" >

        <TextView 
            android:id="@+id/new_textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/movie_title"
            android:paddingTop="10dp"
            android:paddingLeft="7dp"
            android:textSize="15sp" /> <!-- Title of the movie -->

        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/review_by"
            android:paddingTop="3dp"
            android:paddingLeft="7dp"
            android:textSize="12sp" /> <!-- By -->

        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/movie_stars"
            android:paddingTop="3dp"
            android:paddingLeft="7dp"
            android:textSize="12sp" /> <!-- Rating and date -->

        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/sample_string"
            android:maxLines="5"
            android:scrollbars="vertical"
            android:paddingTop="10dp"
            android:paddingLeft="7dp"
            android:textSize="12sp"
            android:layout_gravity="center_vertical|right" /> <!-- Review content -->


    </LinearLayout>

</LinearLayout>
Unexampled answered 29/11, 2013 at 10:36 Comment(5)
Firstly, the orientation for inner and outer layouts are swapped. Also what do you mean by " doesn't seem to work." You don't see anything or you see something but not others?Botswana
I have edited the orientations accordingly. It doesn't start the app, it closes abruptly. The following error is logged in LogCat: "The specified child already has a parent. You must call removeView() on the child's parent first."Unexampled
I think you already have the hierarchy in the XML file. And you try to re-create it. Thats the problem. Please post your XML also..Botswana
So views that are to be loaded dynamically should not be defined/created in XML? Is there a way I could reuse them, say for iteration? I added my XML. Please see above.Unexampled
Regarding to this error, the view should perform something like ((ViewGroup) IV.getParent()).removeView(IV); to leave old parent before add to newParent with newParent.addView(IV).Kennel
J
83

You want that hierarchy programmatically.

- LinearLayout(horizontal) - ImageView - LinearLayout(vertical) - TextView - TextView - TextView - TextView

Ok lets start with Parent LinearLayout

LinearLayout parent = new LinearLayout(context);

parent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
parent.setOrientation(LinearLayout.HORIZONTAL);

//children of parent linearlayout

ImageView iv = new ImageView(context);

LinearLayout layout2 = new LinearLayout(context);

layout2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
layout2.setOrientation(LinearLayout.VERTICAL);

parent.addView(iv);
parent.addView(layout2);

//children of layout2 LinearLayout

TextView tv1 = new TextView(context);
TextView tv2 = new TextView(context);
TextView tv3 = new TextView(context);
TextView tv4 = new TextView(context);

layout2.addView(tv1);
layout2.addView(tv2);
layout2.addView(tv3);
layout2.addView(tv4);

And you are done :)

Jasper answered 1/10, 2014 at 4:10 Comment(3)
Your code throughs this exception: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.Avifauna
How to create LayoutParams with values like width:0dp and height:100dp unlike match_parent and wrap_contentRosannrosanna
I got same error about removeView() #50066268Persaud
B
0

The problem is because the views are already added to the layout in the XML file. Then you findViewById (find them) and try to add them to the layout again. That is why the app crashes complaining that, view already has a parent and you can't add it again.

Botswana answered 29/11, 2013 at 10:57 Comment(0)
L
0

In the XML File LinearLayout already has child view. So there is not need to add them in code.

Lindsay answered 1/10, 2014 at 3:22 Comment(0)
C
-1

i suggest you to remove the xml file and just use full code on the java side. you can add the views programatically from the java side. this one from xtreemdeveloper but i change few line for the parent layout.

// remove this params set it up below
parent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

// change the code above into 
.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
        addContentView(parent,layoutParams);
// end of my change

it will look like this in full code =

   LinearLayout parent = new LinearLayout(context);

    // remove this params set it up below
    parent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

    // change the code above into 
    .LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
            addContentView(parent,layoutParams);
    // end of my change

    parent.setOrientation(LinearLayout.HORIZONTAL);

    //children of parent linearlayout

    ImageView iv = new ImageView(context);

    LinearLayout layout2 = new LinearLayout(context);

    layout2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    layout2.setOrientation(LinearLayout.VERTICAL);

    parent.addView(iv);
    parent.addView(layout2);

    //children of layout2 LinearLayout

    TextView tv1 = new TextView(context);
    TextView tv2 = new TextView(context);
    TextView tv3 = new TextView(context);
    TextView tv4 = new TextView(context);

    layout2.addView(tv1);
    layout2.addView(tv2);
    layout2.addView(tv3);
    layout2.addView(tv4);
Cassette answered 19/10, 2018 at 16:7 Comment(1)
java.lang.IllegalArgumentException: width and height must be > 0 by using thisBalmoral

© 2022 - 2024 — McMap. All rights reserved.