Đứa trẻ được chỉ định đã có cha mẹ. Trước tiên, bạn phải gọi removeView () trên cha mẹ của trẻ (Android)


164

Tôi phải chuyển đổi giữa hai bố trí thường xuyên. Các lỗi đang xảy ra trong bố trí được đăng dưới đây.

Khi bố cục của tôi được gọi lần đầu tiên, sẽ không xảy ra bất kỳ lỗi nào và mọi thứ đều ổn. Sau đó, khi tôi gọi một bố cục khác (một ô trống) và sau đó gọi bố cục của tôi lần thứ hai, nó sẽ đưa ra lỗi sau:

> FATAL EXCEPTION: main
>     java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

Mã bố cục của tôi trông như thế này:

    tv = new TextView(getApplicationContext()); // are initialized somewhere else
    et = new EditText(getApplicationContext()); // in the code


private void ConsoleWindow(){
        runOnUiThread(new Runnable(){

     @Override
     public void run(){

        // MY LAYOUT:
        setContentView(R.layout.activity_console);
        // LINEAR LAYOUT
        LinearLayout layout=new LinearLayout(getApplicationContext());
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout);

        // TEXTVIEW
        layout.addView(tv); //  <==========  ERROR IN THIS LINE DURING 2ND RUN
        // EDITTEXT
        et.setHint("Enter Command");
        layout.addView(et);
        }
    }
}

Tôi biết câu hỏi này đã được hỏi trước đây, nhưng nó không giúp ích gì trong trường hợp của tôi.


1
Chỉ dành cho người mắc lỗi tương tự: Hãy chắc chắn rằng bạn đã thêm phần tử chính xác. Hãy nói rằng bạn phải thêm LinearLayoutnhưng bạn thêm TextView. Vì vậy, sửa chữa nó.
Nhà phát triển

Khi sử dụng cơ sở dữ liệu Android không nên khai báo chế độ xem với id 'root', nó gây ra lỗi tương tự.
Mohammad Reza Khahani

Đối với những người sử dụng TranstitionManager.beginDelayedTransition, vui lòng kiểm tra câu trả lời
mochadwi

Câu trả lời:


354

Thông báo lỗi cho biết bạn nên làm gì.

// TEXTVIEW
if(tv.getParent() != null) {
    ((ViewGroup)tv.getParent()).removeView(tv); // <- fix
}
layout.addView(tv); //  <==========  ERROR IN THIS LINE DURING 2ND RUN
// EDITTEXT

56

chỉ cần truyền đối số đính kèm là sai

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);

2
Đối với tôi, đây là một bullseye. Bố cục hạn chế cho các mục trong recyclView, thay đổi động các ràng buộc dựa trên thời gian chạy. ConstraintSet.apply không hoạt động, cho đến khi này. Vì vậy, tuyên truyền cha mẹ trong onCreateViewHolder, nhưng gửi false là tham số quảng cáo đến lạm phát.
miroslavign

3
Đây là giải pháp đúng đắn! Như @Sniper đã nói, việc chuyển null sang tham số thứ hai có thể khiến chế độ xem con không tự căn chỉnh như bình thường đối với cha mẹ của nó. OTOH vượt qua cha mẹ có thể gây ra lỗi trong câu hỏi. Vì vậy, attachToRoot= false, là con đường để đi.
Vassilis

Cách làm đúng.
Rowland Mtetezi

50

Tôi đến đây để tìm kiếm lỗi với recyclerview của tôi nhưng giải pháp không hoạt động (rõ ràng). Tôi đã viết nguyên nhân và giải pháp cho nó trong trường hợp tái chế. Hy vọng nó sẽ giúp được ai đó.

Lỗi được gây ra nếu onCreateViewHolder()theo phương pháp sau:

layoutInflater = LayoutInflater.from(context);
return new VH(layoutInflater.inflate(R.layout.single_row, parent));

Thay vào đó nên

return new VH(layoutInflater.inflate(R.layout.single_row, null));

15
Đôi khi, những câu trả lời ngẫu nhiên không chính xác là câu trả lời cho những câu hỏi được hỏi sẽ giúp người khác. Điều này làm việc cho tôi. Cảm ơn!
Ajith Memana

1
Đẹp!, Và đó là lý do tại sao mọi người nên thường xuyên vượt qua "null" dưới dạng tham số 2d trong các bộ lọc. Cảm ơn.
siêu người dùng

4
Truyền Null cho tham số chịu trách nhiệm cho cha mẹ không phải là ý tưởng tồi, nhưng bạn phải biết rằng trong trường hợp này, khung nhìn con (cái mà bạn thổi phồng) sẽ không thể tự đo chính xác trong một số trường hợp, bởi vì nó không biết bất cứ điều gì về cha mẹ. Trong một số trường hợp, nó sẽ hoạt động nhưng trong một số trường hợp thì không.
Stoycho Andreev

1
Lưu ý rằng điều này có thể khiến chủ đề người xem không được giải quyết chính xác.
SpaceBison

13

Tôi đã nhận được thông báo này trong khi cố gắng thực hiện một đoạn bằng cách sử dụng Đính kèm vào gốc thành đúng thay vì sai, như vậy:

return inflater.inflate(R.layout.fragment_profile, container, true)

Sau khi làm:

return inflater.inflate(R.layout.fragment_profile, container, false)

Nó đã làm việc.


5

Nếu giải pháp khác không hoạt động như:

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);

kiểm tra xem bạn đang trở về từ onCreateView của đoạn nào là chế độ xem đơn hay nhóm xem? trong trường hợp của tôi, tôi đã có viewpager trên root xml của đoạn và tôi đang trả về viewpager, khi tôi thêm viewgroup trong layout tôi không cập nhật rằng tôi phải quay lại viewgroup ngay bây giờ, không phải viewpager (view).


5

frameLayout.addView (bannerAdView); <----- nếu bạn gặp lỗi trên dòng này, hãy làm như dưới đây ..

if (bannerAdView.getParent() != null)

  ((ViewGroup) bannerAdView.getParent()).removeView(bannerAdView);

   frameLayout.addView(bannerAdView);     <------ now added view

4

Lỗi của tôi là xác định chế độ xem như thế này:

view = inflater.inflate(R.layout.qr_fragment, container);

Nó đã mất tích:

view = inflater.inflate(R.layout.qr_fragment, container, false);

3

Trong trường hợp của tôi, vấn đề xảy ra là do tôi đang thổi phồng bố mẹ với <merge>bố cục. Trong trường hợp này, addView()gây ra vụ tai nạn.

View to_add = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, true);
// parent_layout.addView(to_add); // THIS CAUSED THE CRASH

Loại bỏ addView()giúp giải quyết vấn đề.


2

kiểm tra xem bạn đã thêm chế độ xem chưa

if (textView.getParent() == null)
    layout.addView(textView);

2

Mã dưới đây đã giải quyết nó cho tôi:

@Override
public void onDestroyView() {
    if (getView() != null) {
        ViewGroup parent = (ViewGroup) getView().getParent();
        parent.removeAllViews();
    }
    super.onDestroyView();
}

Lưu ý: Lỗi là từ lớp phân đoạn của tôi và bằng cách ghi đè phương thức onDestroy như thế này, tôi có thể giải quyết nó.



2

Trong trường hợp của tôi, điều đó xảy ra khi tôi muốn thêm chế độ xem của phụ huynh vào chế độ xem khác

View root = inflater.inflate(R.layout.single, null);
LinearLayout lyt = root.findViewById(R.id.lytRoot);
lytAll.addView(lyt);  // ->  crash

bạn phải thêm chế độ xem cha mẹ như thế này

View root = inflater.inflate(R.layout.single, null);
LinearLayout lyt = root.findViewById(R.id.lytRoot);
lytAll.addView(root);

2

Trước tiên, bạn phải xóa chế độ xem con khỏi cha mẹ của nó.

Nếu dự án của bạn nằm trong Kotlin, giải pháp của bạn sẽ trông hơi khác so với Java. Kotlin đơn giản hóa việc truyền với as?, trả về null nếu bên trái là null hoặc không thành công.

(childView.parent as? ViewGroup)?.removeView(childView)
newParent.addView(childView)

Giải pháp mở rộng Kotlin

Nếu bạn cần làm điều này nhiều lần, hãy thêm tiện ích mở rộng này để mã của bạn dễ đọc hơn.

childView.removeSelf()

fun View?.removeSelf() {
    this ?: return
    val parentView = parent as? ViewGroup ?: return
    parentView.removeView(this)
}

Nó sẽ không làm gì một cách an toàn nếu Chế độ xem này là null, chế độ xem chính là null hoặc chế độ xem chính không phải là một Viewgroup


1

Tôi tìm thấy một sửa chữa khác:

if (mView.getParent() == null) {
                    myDialog = new Dialog(MainActivity.this);
                    myDialog.setContentView(mView);
                    createAlgorithmDialog();
                } else {
                    createAlgorithmDialog();
                }

Ở đây tôi chỉ có một câu lệnh if kiểm tra xem khung nhìn có cha hay không và nếu nó không Tạo hộp thoại mới, hãy đặt contentView và hiển thị hộp thoại trong phương thức "createAlacticmDialog ()" của tôi.

Điều này cũng đặt các nút tích cực và tiêu cực (nút ok và hủy) với onClickListener.


0

Bạn có thể sử dụng methode này để kiểm tra xem một view có con hay không.

public static boolean hasChildren(ViewGroup viewGroup) {
    return viewGroup.getChildCount() > 0;
 }

0

Trường hợp của tôi khác với chế độ xem con đã có chế độ xem cha mẹ Tôi đang thêm chế độ xem con bên trong chế độ xem cha mẹ vào bố mẹ khác. mã ví dụ dưới đây

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/lineGap"
>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/black1"
    android:layout_gravity="center"
    android:gravity="center"
    />

</LinearLayout>

Và tôi đã thổi phồng khung nhìn này và thêm vào một linearLayout khác, sau đó tôi loại bỏ LinaarLayout khỏi bố cục trên và nó bắt đầu hoạt động

mã dưới đây đã khắc phục sự cố:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:gravity="center"
   android:textColor="@color/black1" />

0

Vấn đề của tôi liên quan đến nhiều câu trả lời khác, nhưng một chút lý do khác nhau để cần thực hiện thay đổi ... Tôi đã cố gắng chuyển đổi một Hoạt động thành một Mảnh vỡ. Vì vậy, tôi đã chuyển mã lạm phát từ onCreate sang onCreateView, nhưng tôi quên chuyển đổi từ setContentView sang phương thức lạm phát và chính IllegalStateException đã đưa tôi đến trang này.

Tôi đã thay đổi điều này:

binding = DataBindingUtil.setContentView(requireActivity(), R.layout.my_fragment)

đến đây:

binding = DataBindingUtil.inflate(inflater, R.layout.my_fragment, container, false)

Điều đó đã giải quyết vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.