IllegalStateException: 指定的子节点已经有一个父节点

我使用的是片段,当我第一次实例化一个片段的时候。但是第二次我得到了这个例外。我找不到错误出现的地方?

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

第一次是 OK 的时候,我从 list 中单击 element2,它也是 OK 的; 但是当我返回 element1时,我得到了这个 bug。

谢谢大家!

110772 次浏览

You are adding a View into a layout, but the View already is in another layout. A View can't be in more than one place.

When you override OnCreateView in your RouteSearchFragment class, do you have the

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

code segment?

If so, removing the return statement should solve your problem.

You can keep the code and return the view if you don't want to regenerate view data, and onDestroyView() method you remove this view from its parent like so:

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

Sorry to post to an old question but I was able to fix it using a totally different solution. I was getting this exception but I changed the first line of my onCreatView override from this:

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

...to this:

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

I have no idea why but using the override that accepts the boolean as the third param fixed it. I think it tells the Fragment and/or Activity not to use the "container" as the parent of the newly-created View.

I have facing this issue many time. Please add following code for resolve this issue :

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

Thanks

I had this code in a fragment and it was crashing if I try to come back to this fragment

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

after gathering the answers on this thread, I realised that mRootView's parent still have mRootView as child. So, this was my fix.

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

hope this helps

This solution can help :

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

If you have this statement..

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

Then try this.. Add false as third argument.. May be it could help..

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

It also happens when the view returned by onCreateView() isn't the view that was inflated.

Example:

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;

Fix:

return rootView;

Instead of:

return textView; // or whatever you returned

I had this problem and couldn't solve it in Java code. The problem was with my xml.

I was trying to add a textView to a container, but had wrapped the textView inside a LinearLayout.

This was the original xml file:

<?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>

Now with the LinearLayout removed:

<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"/>

This didn't seem like much to me but it did the trick, and I didn't change my Java code at all. It was all in the xml.

in your xml file you should set layout_width and layout_height from wrap_content to match_parent. it's fixed for me.

<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

I solved it by setting attachToRoot of inflater.inflate() to false.

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

I used to get these when adding a custom view to a FrameLayout. I did this:

if (this.chartFrame.indexOfChild(mark.markView) == -1)
this.chartFrame.addView(mark.markView);

Which checked to see if it was already in the layout. Seemed to work until I saw an error today for the first time in years on API 31 (Android 12). Not sure what is happening yet,