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(); 前添加视图布局
ρяσѕρєяķ

@imrankhan错了!您可以添加而不删除所有内容。最重要的部分丢失了,因为stacktrace中没有自定义包,所以建议您删除一些代码并逐步进行测试...
WarrenFaith 2012年

1
我添加了更多详细信息,请您看到吗?
haythem souissi 2012年

这个RouteSearchFragment类是什么?在Android文档中找不到任何参考。请也更新类定义。
noob 2012年

Answers:


36

当您OnCreateViewRouteSearchFragment课堂上重写时,您是否拥有

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

代码段?

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

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

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

5
@Override public void onDestroyView(){super.onDestroyView(); ViewGroup parentViewGroup =(ViewGroup)mRoutesSearchViewContainer.getParent(); if(null!= parentViewGroup){parentViewGroup.removeView(mRoutesSearchViewContainer); }
haythem souissi 2012年

@Medo:你能对此做一个简短的解释。我在logcat中显示了相同的错误。正如您给出的建议“删除return语句应解决您的问题”,但我们需要在onCreateView()方法中返回View对象。您可以提供摘要代码进行解释吗?谢谢。
克里希纳·普拉萨德

@Krishna只需像平常一样膨胀并返回视图。您可以跳过整个if语句。
Medo

65
对于我来说,我只是不得不更换return inflater.inflate(R.layout.fragment_search, container);return inflater.inflate(R.layout.fragment_search, container, false);
苏菲安

370

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

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

...对此:

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

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


53
别后悔-这对我和其他许多人都非常有用。谢谢!

非常感谢,我一直忘了这个,并回到了这个答案
noloman

@Patrick,第一个将膨胀视图附加到容器,添加false标志指定您不想将膨胀视图添加到容器。
Ne0

而且我继续回到这篇文章,发现这是答案:)
noloman

45

我已经面对这个问题很多次了。请添加以下代码以解决此问题:

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

谢谢


谢谢您的解决方案:)我有一个非常特殊的情况,我不能使用充气机来解决这个问题。您为我节省了很多时间
Bojan 2013年

抱歉,我不太了解我是Android新手。
Zin Win Htet 2014年

在view.getParent(); 剂量查看对象从何而来?
Zin Win Htet 2014年

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 2014年

哇!终于对我有用!解决方案。谢谢!
avisper '17

我没有理由说为什么“(ViewGroup)mRootView.getParent())。removeView(mRootView);” 与直接调用“ <WhateverIsParentViewGroupName> .removeView(mRootView)”相反,但这对我也有效,我正在Android 8.0和9.0上进行测试。感谢芽^

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

要添加Viewlayout,但视图已经是另一个layout。一个视图不能位于多个地方。


我为问题添加了更多详细信息,请您看到吗?
haythem souissi 2012年

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始终为null,因为您没有对其进行初始化。
Zin Win Htet 2014年

rootView始终为空
Thinsky 2015年

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文件中,您应该将wrap_content的layout_width和layout_height设置为match_parent。这对我来说是固定的。

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.