在 LinearLayout.addView() 和 Linearlayout.removeView() 之后出现错误 "The specified child already has a parent"

Error "The specified child already has a parent" after LinearLayout.addView() and then Linearlayout.removeView()

我正在做一个项目,我在 activity_main.xml 上创建了一个 parent 带有 id=linear_parent 的 LinearLayout。在这个 parent 布局中,根据用户在 EditText (id=no_of_views_input ). 在每个线性布局中,还有更多 child 视图(imageView、编辑、按钮)以编程方式创建。

假设用户输入 4 no_of_views_input,视图层次结构类似于,

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

  1. linear_parent
    • linearLayout //位置1
      • imageView
      • 编辑
      • 按钮
    • linearLayout //位置2
      • imageView
      • 编辑
      • 按钮
    • linearLayout //位置3
      • imageView
      • 编辑
      • 按钮
    • linearLayout //位置4
      • imageView
      • 编辑
      • 按钮

===========

创建这些布局和视图后,我想根据来自 child id=edit 的用户输入重新排列 LinearLayouts。 假设用户在LinearLayout位置3的edit输入1,我想要的是,当前位置3的LinearLayout必须连同它的children一起添加到位置1,并且最后删除位于位置 3 的旧 Linearlayout。(如果索引向下移动,当前将位于位置 4)。

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();
                }
            }
        });
    }
}

我得到的错误是
java.lang.IllegalStateException: 指定的 child 已经有一个 parent。您必须先在 child 的 parent 上调用 removeView()。
任何帮助将不胜感激。

在将子视图添加为子视图之前尝试从其父视图中移除子视图:

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();
}

但是,请考虑切换到 RecyclerView
它将简化您的代码结构。