Home > Blockchain >  Error "The specified child already has a parent" after LinearLayout.addView() and then Lin
Error "The specified child already has a parent" after LinearLayout.addView() and then Lin

Time:02-20

I'm working on a project where I have a parent LinearLayout with id=linear_parent created on activity_main.xml. Inside this parent layout, n numbers of LinearLayouts are created programmatically base on user input at EditText (id=no_of_views_input). And inside the each of these Linearlayouts, there are more child views (imageView, edit, button) created programmatically.

Suppose a user enters 4 no_of_views_input, the views heirarchy would be something like,

============

  1. linear_parent
    • linearLayout //position 1
      • imageView
      • edit
      • button
    • linearLayout //position 2
      • imageView
      • edit
      • button
    • linearLayout //position 3
      • imageView
      • edit
      • button
    • linearLayout //position 4
      • imageView
      • edit
      • button

===========

After these layouts and views are created, I want to rearrange the LinearLayouts, base on user input from child id=edit. Suppose the user enters 1 on edit at LinearLayout position 3 , what I want is, the current LinearLayout at position 3 must be added to position 1 along with its children, and finally remove the old Linearlayout which was at position 3. (would be currently at position 4 if indexes are shifted down).

activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    
    <LinearLayout
        android:id="@ id/linear_parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:gravity="center"
        android:orientation="vertical">

               <!-- Views are added here programmatically -->

    </LinearLayout>
    
    <EditText
        android:id="@ id/no_of_views_input"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:hint="Number of view to add"/>
    <Button
        android:id="@ id/add_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    LinearLayout linear_parent;
    Button add_button;
    EditText no_of_views_input;

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

        linear_parent = findViewById(R.id.linear_parent);
        add_button= findViewById(R.id.add_button);
        no_of_views_input= findViewById(R.id.no_of_views_input);

        no_of_views_input.setInputType(InputType.TYPE_CLASS_NUMBER);

        add_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!no_of_views_input.getText().toString().isEmpty()) {

                    String no_of_views_temp = no_of_views_input.getText().toString();
                    int no_of_views = Integer.parseInt(no_of_views_temp);

                    for (int i = 0; i < no_of_views; i  ) {
                        LinearLayout linearLayout = new LinearLayout(MainActivity.this);
                        LinearLayout.LayoutParams lp_ll = new LinearLayout.LayoutParams(600, 1500);
                        lp_ll.setMargins(0, 50, 0, 0);
                        linearLayout.setOrientation(LinearLayout.VERTICAL);
                        linearLayout.setId(View.generateViewId()); // id = 1, 2, 3, 4, ...
                        int linearLayoutID = linearLayout.getId();
                        linearLayout.setLayoutParams(lp_ll);

                        ImageView imageView = new ImageView(MainActivity.this);
                        LinearLayout.LayoutParams lp_image = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 800);
                        imageView.setBackgroundColor(Color.Yellow);
                        imageView.setLayoutParams(lp_image);

                        EditText edit = new EditText(MainActivity.this);
                        LinearLayout.LayoutParams lp_edit = new LinearLayout.LayoutParams(300, ViewGroup.LayoutParams.WRAP_CONTENT);
                        edit.setBackgroundColor(Color.WHITE);
                        edit.setInputType(InputType.TYPE_CLASS_NUMBER);
                        edit.setHint("move to index");
                        edit.setLayoutParams(lp_edit);

                        Button button = new Button(MainActivity.this);
                        LinearLayout.LayoutParams lp_button= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                        button.setBackgroundColor(Color.BLUE);
                        button.setText("Move");
                        button.setLayoutParams(lp_button);

                        linear_parent.addView(linearLayout);

                        linearLayout.addView(imageView);
                        linearLayout.addView(edit);
                        linearLayout.addView(button);
             
                        button.setOnClickListener(new View.OnClickListener() {
                           @Override
                           public void onClick(View view) {
                               String indexTarget_temp = edit.getText().toString();
                               int indexTarget = Integer.parseInt(indexTarget_temp );

                               int childCount = linear_parent.getChildCount();
                               int currentLinearLayoutPos = linear_parent.indexOfChild(linearLayout);
                               
                               try {
                                   linear_parent.addView(linearLayout, indexTarget - 1); //adding current linearLayout to indexTarget  
//error occurs this line
                         
                            linear_parent.removeView(linear_parent.getChildAt(currentLinearLayoutPos   1)); //removing linearLayout at old index
                               }
                               catch(IllegalStateException e) {
                                   e.printStackTrace();
                               }
                               
                           }
                        });
                        
                    }

                }else {
                    Toast.makeText(MainActivity.this, "Enter index no", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

The error I'm getting is
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Any help would be highly appreciated.

CodePudding user response:

Try to remove the child from its parent before adding it as a subview:

try {
    if (linearLayout.getParent() != null) {
        // Remove child from parent
        ((ViewGroup) linearLayout.getParent()).removeView(linearLayout)
    }
    linear_parent.addView(linearLayout, indexTarget - 1); 
}
catch(IllegalStateException e) {
   e.printStackTrace();
}

However, consider switching to a RecyclerView.
It would simplify your code structure.

  • Related