Android java.lang.IllegalStateException: 指定的孩子已经有一个父母

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10007094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:09:29  来源:igfitidea点击:

java.lang.IllegalStateException: The specified child already has a parent

androidandroid-layoutandroid-fragments

提问by haythem souissi

I am using fragments, when I instantiate a fragment the first time it it. but the second time I got this exception. I couldn't find the line where I got the error?

我正在使用片段,当我第一次实例化片段时。但是第二次我得到了这个例外。我找不到出错的那一行?

 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.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)

Here are what i do when i click on an element of my list fragment.

当我单击列表片段的元素时,我会执行以下操作。

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

The first time it is Ok, I click element2 from list, it's also ok; but when I return to element1 I got this bug.

第一次ok,我点list中的element2,也ok;但是当我返回 element1 时,我遇到了这个错误。

Thanks every one!

谢谢大家!

采纳答案by Medo

When you override OnCreateViewin your RouteSearchFragmentclass, do you have the

当你OnCreateView在你的RouteSearchFragment班级中覆盖时,你有

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

code segment?

代码段?

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

如果是这样,删除 return 语句应该可以解决您的问题。

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:

如果您不想重新生成视图数据,您可以保留代码并返回视图,并且 onDestroyView() 方法可以从其父视图中删除此视图,如下所示:

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

回答by Patrick

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:

很抱歉发布一个旧问题,但我能够使用完全不同的解决方案来修复它。我收到此异常,但我更改了 onCreatView 覆盖的第一行:

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.

我不知道为什么但是使用接受布尔值的覆盖作为第三个参数来修复它。我认为它告诉 Fragment 和/或 Activity 不要使用“容器”作为新创建视图的父级。

回答by Hardik

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

谢谢

回答by Dhananjay M

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

然后试试这个..添加false作为第三个参数..可能会有所帮助..

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

回答by user1736525

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.

在此线程上收集答案后,我意识到 mRootView 的父级仍然将 mRootView 作为子级。所以,这是我的修复。

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

hope this helps

希望这可以帮助

回答by Mateus Pires

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

当 onCreateView() 返回的视图不是膨胀的视图时,也会发生这种情况。

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

回答by DroidCrafter

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

我遇到了这个问题,无法用 Java 代码解决。问题出在我的 xml 上。

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

我试图将 textView 添加到容器中,但已将 textView 包装在 LinearLayout 中。

This was the original xml file:

这是原始的 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>

Now with the LinearLayout removed:

现在删除了 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"/>

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.

这对我来说似乎没什么,但它确实有效,而且我根本没有更改我的 Java 代码。这一切都在xml中。

回答by noob

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

您正在将 a 添加View到 a 中layout,但 View 已经在 another 中layout。一个视图不能位于多个地方。

回答by Mr. B.

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

我通过设置解决了它attachToRootinflater.inflate()false

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

回答by Bhavit S. Sengar

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