java.lang.IllegalStateException: เด็กที่ระบุมีพาเรนต์อยู่แล้ว


99

ฉันกำลังใช้ชิ้นส่วนเมื่อฉันสร้างชิ้นส่วนในครั้งแรก แต่ครั้งที่สองฉันได้รับข้อยกเว้นนี้ ฉันไม่พบบรรทัดที่ฉันได้รับข้อผิดพลาด?

 04-04 08:51:54.320: E/AndroidRuntime(29713): FATAL EXCEPTION: main
    04-04 08:51:54.320: E/AndroidRuntime(29713): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addViewInner(ViewGroup.java:3013)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2902)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2859)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2839)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.NoSaveStateFrameLayout.wrap(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.BackStackRecord.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl$1.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Handler.handleCallback(Handler.java:587)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Handler.dispatchMessage(Handler.java:92)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Looper.loop(Looper.java:132)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.app.ActivityThread.main(ActivityThread.java:4126)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at java.lang.reflect.Method.invokeNative(Native Method)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at java.lang.reflect.Method.invoke(Method.java:491)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at dalvik.system.NativeStart.main(Native Method)

นี่คือสิ่งที่ฉันทำเมื่อฉันคลิกที่องค์ประกอบของส่วนรายการของฉัน

// If we are not currently showing a fragment for the new
 // position, we need to create and install a new one.
 RouteSearchFragment df = RouteSearchFragment.newInstance(index);

 // Execute a transaction, replacing any existing fragment
 // with this one inside the frame.
 FragmentTransaction ft = fragmentManager.beginTransaction();
 ft.replace(R.id.details_full, df);
 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
 ft.commit();

ครั้งแรกที่ตกลงฉันคลิก element2 จากรายการก็ใช้ได้เช่นกัน แต่เมื่อฉันกลับไปที่ element1 ฉันพบจุดบกพร่องนี้

ขอบคุณทุกคน!


ต้องเรียก layoutView.removeAllViews (); ก่อนเพิ่มมุมมองในการจัดวาง
ρяσѕρєя K

@imrankhan ผิด! คุณสามารถเพิ่มโดยไม่ต้องลบทั้งหมด ส่วนที่สำคัญที่สุดหายไปและเนื่องจากไม่มีแพ็คเกจที่กำหนดเองใน stacktrace ฉันขอแนะนำให้คุณลบโค้ดบางส่วนและทดสอบทีละขั้นตอน ...
WarrenFaith

1
ฉันเพิ่มรายละเอียดเพิ่มเติมโปรดดูที่?
haythem souissi

คลาส RouteSearchFragment นี้คืออะไร ?? ไม่พบข้อมูลอ้างอิงใด ๆ ในเอกสาร Android โปรดอัปเดตคำจำกัดความของชั้นเรียนด้วย
noob

คำตอบ:


36

เมื่อคุณแทนที่OnCreateViewในRouteSearchFragmentชั้นเรียนของคุณคุณมีไฟล์

if(view != null) {
    return view; 
}

ส่วนรหัส?

ถ้าเป็นเช่นนั้นการลบคำสั่งส่งคืนจะช่วยแก้ปัญหาของคุณได้

คุณสามารถเก็บรหัสและส่งคืนมุมมองได้หากคุณไม่ต้องการสร้างข้อมูลมุมมองใหม่และวิธี onDestroyView () คุณจะลบมุมมองนี้ออกจากระดับบนสุดดังนี้:

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

5
@Override โมฆะสาธารณะ onDestroyView () {super.onDestroyView (); ViewGroup parentViewGroup = (ViewGroup) mRoutesSearchViewContainer.getParent (); ถ้า (null! = parentViewGroup) {parentViewGroup.removeView (mRoutesSearchViewContainer); }}
haythem souissi

@Medo: คุณช่วยอธิบายสั้น ๆ เกี่ยวกับเรื่องนี้ได้ไหม ฉันมีข้อผิดพลาดเดียวกันกับที่แสดงใน logcat ตามที่คุณได้ให้คำแนะนำ "ลบคำสั่ง return ควรแก้ปัญหาของคุณ" แต่เราจำเป็นต้องส่งคืน View object ในเมธอด onCreateView () คุณสามารถให้ข้อมูลโค้ดสำหรับคำอธิบายของคุณ ขอบคุณ.
Krishna Prasad

@ กฤษณะเพียงแค่ขยายและคืนมุมมองตามปกติ คุณสามารถข้ามคำสั่ง if ทั้งหมดได้
Medo

65
สำหรับฉันฉันต้องแทนที่return inflater.inflate(R.layout.fragment_search, container);ด้วยreturn inflater.inflate(R.layout.fragment_search, container, false);
Sufian

370

ขออภัยที่ต้องโพสต์คำถามเก่า แต่ฉันสามารถแก้ไขได้โดยใช้วิธีแก้ปัญหาที่แตกต่างกันโดยสิ้นเชิง ฉันได้รับข้อยกเว้นนี้ แต่ฉันเปลี่ยนบรรทัดแรกของการแทนที่ onCreatView จากสิ่งนี้:

View result = inflater.inflate(R.layout.customer_layout, container);

...สำหรับสิ่งนี้:

View result = inflater.inflate(R.layout.customer_layout, container, false);

ฉันไม่รู้ว่าทำไมถึงใช้การแทนที่ที่ยอมรับบูลีนเป็นพารามิเตอร์ตัวที่สามแก้ไขได้ ฉันคิดว่ามันบอก Fragment และ / หรือ Activity ไม่ให้ใช้ "container" เป็นพาเรนต์ของ View ที่สร้างขึ้นใหม่


53
อย่าเสียใจ - สิ่งนี้มีประโยชน์สำหรับฉันมากและเห็นได้ชัดว่ามีคนอื่น ๆ ขอบคุณ!
อ่านรหัส

ขอบคุณมากฉันลืมสิ่งนี้ไป
เรื่อย ๆ

@Patrick ขั้นแรกแนบมุมมองที่สูงเกินจริงเข้ากับคอนเทนเนอร์การเพิ่มแฟล็กเท็จระบุว่าคุณไม่ต้องการเพิ่มมุมมองที่สูงเกินจริงไปยังคอนเทนเนอร์
Ne0

และฉันกลับมาที่โพสต์นี้
เรื่อย ๆ

45

ฉันประสบปัญหานี้หลายครั้ง โปรดเพิ่มรหัสต่อไปนี้เพื่อแก้ไขปัญหานี้:

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

ขอบคุณ


ขอบคุณสำหรับวิธีแก้ปัญหานี้ :) ฉันมีกรณีเฉพาะที่ฉันไม่สามารถใช้พองเพื่อแก้ปัญหานี้ได้ คุณช่วยฉันได้มาก
Bojan

ฉันขอโทษฉันไม่ค่อยเข้าใจเพราะฉันเพิ่งเริ่มใช้ Android
Zin Win Htet

ใน view.getParent (); วัตถุดูขนาดยามาจากไหน?
Zin Win Htet

Cristy YG: ใช้อินสแตนซ์ View เป็นตัวแปรส่วนกลางและขยาย xml เลย์เอาต์ของคุณบนตัวแปรส่วนกลาง คุณติดตามฉันหรือไม่?
Hardik

ใช่ดูอินสแตนซ์ประกาศเป็นส่วนกลาง
Hardik

35

ถ้าคุณมีคำพูดนี้ ..

View view = inflater.inflate(R.layout.fragment1, container);//may be Incorrect 

ลองทำตามนี้ .. เพิ่ม false เป็นอาร์กิวเมนต์ที่สาม .. อาจช่วยได้ ..

View view = inflater.inflate(R.layout.fragment1, container, false);//correct one

21

ฉันมีรหัสนี้ในส่วนและมันขัดข้องถ้าฉันพยายามกลับมาที่ส่วนนี้

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} 

หลังจากรวบรวมคำตอบในชุดข้อความนี้แล้วฉันก็รู้ว่าแม่ของ mRootView ยังคงมี mRootView เป็นลูก นี่คือการแก้ไขของฉัน

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} else {
    ((ViewGroup) mRootView.getParent()).removeView(mRootView);
}

หวังว่านี่จะช่วยได้


2
+1 ช่วยฉันด้วย โดยเฉพาะอย่างยิ่งถ้ากิจกรรมของคุณยังคงอยู่ แต่ตัวจัดการส่วนกำลังเพิ่มส่วนใหม่ที่ด้านบน เมื่อกลับไปที่ส่วนแรกต้องตรวจสอบให้แน่ใจว่าได้ลบมุมมองรูทเก่าแล้ว ขอบคุณ!
Bundeeteddee

มันช่วยฉันได้มาก ฉันหาวิธีแก้ปัญหานั้นมา 3 วันแล้ว คำตอบที่ง่ายและสวย
Zin Win Htet

ว้าว! ในที่สุดมันก็ได้ผลสำหรับฉัน! โซลูชันฟรี ขอบคุณ!
avisper

ฉันไม่มีเหตุผลว่าทำไม "(ViewGroup) mRootView.getParent ()). removeView (mRootView);" ใช้งานได้ตรงกันข้ามกับการเรียกโดยตรง "<WhateverIsParentViewGroupName> .removeView (mRootView)" แต่ก็ใช้ได้กับฉันเช่นกันฉันกำลังทดสอบบน Android 8.0 และ 9.0 ขอบคุณครับ ^
Khay

16

นอกจากนี้ยังเกิดขึ้นเมื่อมุมมองที่ส่งคืนโดย onCreateView () ไม่ใช่มุมมองที่สูงเกินจริง

ตัวอย่าง:

View rootView = inflater.inflate(R.layout.my_fragment, container, false);

TextView textView = (TextView) rootView.findViewById(R.id.text_view);
textView.setText("Some text.");

return textView;

แก้ไข:

return rootView;

แทน:

return textView; // or whatever you returned

ขอบคุณ! มันช่วยฉัน!
Sudheesh Mohan

5

ฉันมีปัญหานี้และไม่สามารถแก้ไขได้ในโค้ด Java ปัญหาเกิดกับ xml ของฉัน

ฉันพยายามเพิ่ม textView ลงในคอนเทนเนอร์ แต่ได้รวม textView ไว้ใน LinearLayout

นี่คือไฟล์ xml ดั้งเดิม:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

</LinearLayout>

ตอนนี้ลบ LinearLayout แล้ว:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

สิ่งนี้ดูเหมือนจะไม่มากสำหรับฉัน แต่มันก็เป็นเคล็ดลับและฉันไม่ได้เปลี่ยนรหัส Java เลย ทั้งหมดอยู่ใน xml


2

คุณกำลังเพิ่มViewลงใน a layoutแต่มุมมองนั้นอยู่ในอีกมุมมองหนึ่งlayoutแล้ว มุมมองต้องไม่อยู่ในที่มากกว่าหนึ่งแห่ง


ฉันได้เพิ่มรายละเอียดเพิ่มเติมในคำถามของฉันโปรดดูที่?
haythem souissi

1

โซลูชันนี้สามารถช่วย:

public class FragmentItem extends Android.Support.V4.App.Fragment
{
    View rootView;
    TextView textView;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView != null) 
        {
            ViewGroup parent = (ViewGroup)rootView.Parent;
            parent.RemoveView(rootView);
        } else {
            rootView = inflater.Inflate(Resource.Layout.FragmentItem, container, false);
            textView = rootView.FindViewById<TextView>(Resource.Id.textViewDisplay);            
        }
        return rootView;
    }
}

1
ฉันคิดว่า rootView จะเป็นโมฆะเสมอเนื่องจากคุณไม่ได้เริ่มต้น
Zin Win Htet

rootView เป็นโมฆะเสมอ
Thinsky

1

ฉันจะแก้ไขได้โดยการตั้งค่าattachToRootของการinflater.inflate()false

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_overview, container, false);
    return view;
}

0

ในไฟล์ xml ของคุณคุณควรตั้งค่า layout_width และ layout_height จาก wrap_content เป็น match_parent มันคงสำหรับฉัน

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.