0

The scenario is, When the user clicks the button, I need to add particular layout in known position of parent layout for the number of times button clicked.

I don't know whether it works or not. I tried this following solution which I got from other posts

Buttononclicklistenercode is,

    parent = (ViewGroup) C.getParent();//c is a layout in which position i want to add view
    final int index = parent.indexOfChild(C);
    tobeadded=getLayoutInflater().inflate(R.layout.block_tobeadded_foremi,null);
    ((Button)findViewById(R.id.button88)).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addviewcount+=1;
            LinearLayout addinglayout=new LinearLayout(MyActivity.this);
            addinglayout.setOrientation(LinearLayout.VERTICAL);
            parent.removeViewAt(index);
            addinglayout.removeAllViews();
            for(int i=0;i<addviewcount;i++)
                   addinglayout.addView(tobeadded);
            parent.addView(addinglayout, index);
        }
    });

But I am getting java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. In my code, before adding that layout, I have invoked the method removeViewAt() for parent.

Can anyone help me to know what is wrong in that.And Is there any other way to do this? Thanks in advance!

Jyoti JK
  • 2,141
  • 1
  • 17
  • 40
  • What exactly you want,Are you want to remove the previous layout and then replace new layout in place of that or you want to only add the layout on click of button? – Nilam Vaddoriya Dec 01 '17 at 06:13
  • I just want to add one more view to that layout(`addinglayout`) when the button is clicked – Jyoti JK Dec 01 '17 at 06:16
  • Try this [link](https://stackoverflow.com/questions/47505356/i-want-to-add-dynamic-layout-with-text-view-and-edit-text-on-button-click-for-n/47506219#47506219), might fulfill your requirement. – Manish Singh Rana Dec 01 '17 at 06:19
  • 1
    In your for loop you are adding ' addviewcount ' times 'tobeadded'. that's why you are getting this error. first you must call removeview in your loop also – Bek Dec 01 '17 at 06:23
  • 1
    Calling removeView outside of for is useless. It throwing exception because consider i is '0' in for loop it will add view using "addinglayout.addView(tobeadded);" now when i will increment to '1' it will try to add view again, but what about view which is added at '0'(when i is '0'). – Abhishek Dec 01 '17 at 06:24
  • @Joe add more code like which view you want to add, inside of which view new view are going to add(parent points to which type of layout like Relative or Linear etc.) – Abhishek Dec 01 '17 at 06:27

3 Answers3

2

You are getting an IllegalStateException because you've already attached the child to the root of the layout.

parent.removeViewAt(index);
addinglayout.removeAllViews();
for(int i=0;i<addviewcount;i++)
     addinglayout.addView(tobeadded);//Exception in this line
parent.addView(addinglayout, index);

Let's say addviewcount is 2.

Now in the first iteration, tobeadded is attached to addinglayout.

In the second iteration, you're again trying to attach tobeadded to addinglayout which results in an exception, since The specified child already has a parent. To solve this, You must call removeView() on the child's parent first.

All in all no child is supposed to have more than one parent. And the way you're implementing what you're trying to do is wrong. Create an array of View objects and attach them to the layout in a loop. This will solve your problem.

Here's a link where I've answered a similar question in detail few months back. https://stackoverflow.com/a/46672959/2356570

capt.swag
  • 10,335
  • 2
  • 41
  • 41
1
 LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
                              LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);

On Click of button try this:

addinglayout.removeAllViews();
View text = new View(context);
textNotes.setLayoutParams(lparams);
addinglayout.addView(text);
Nilam Vaddoriya
  • 433
  • 2
  • 10
1
public class SampleDynamiclay extends AppCompatActivity {

Button add, replace;
LinearLayout dynamiclay;
int newid = 100;
int replaceid;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sampledynamiclay);

    add = (Button) this.findViewById(R.id.add);
    replace = (Button) this.findViewById(R.id.replace);
    dynamiclay = (LinearLayout) this.findViewById(R.id.dynamiclay);

    add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            TextView txt = new TextView(SampleDynamiclay.this);
            txt.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            newid = newid + 1;
            txt.setTag(newid + "");
            txt.setTextColor(getResources().getColor(R.color.black));
            txt.setText("TextView  " + newid);
            dynamiclay.addView(txt);
        }
    });

    replace.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            newid = newid + 1;
            View removableView = dynamiclay.getChildAt(2);
            dynamiclay.removeView(removableView);
            TextView txt = new TextView(SampleDynamiclay.this);
            txt.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            txt.setTag(newid + "");
            txt.setTextColor(getResources().getColor(R.color.black));
            txt.setText("TextView is replaced " + newid);
            dynamiclay.addView(txt, 2);


        }
    });

}

}

response screenshot in mobile of above code