删除所有子片段

时间:2014-06-23 10:05:55

标签: android android-fragments fragmentmanager

我有一个片段,xml包含这样的内容:

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="230dp">

        <fragment
            android:id="@+id/myFragmen1"
            android:name="com...widgets.myViewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/text""/>

    </RelativeLayout>

我需要在xml中添加4个不同的片段。父片段我这样开始:

getFragmentManager().beginTransaction()
            .replace(R.id.frameContainer, myFragment1)
            .addToBackStack(null)
            .commit();

所以,一切正常,直到我试图显示片段超过1次。如果我再次单击并尝试再次打开片段,那么我会得到这些错误:

 Caused by: java.lang.IllegalArgumentException: Binary XML file line #17: Duplicate id 0x7f080130, tag null, or parent id 0xffffffff with another fragment for com...widgets.myViewPager

我知道问题,也有解决方案。我可以删除onDestroy中的片段。但是,这个我不想做! 包含另一个片段的xml是动态的。我正在通过bundle获得布局,所以在这个片段中我不知道,显示了哪个片段。如果我使用这个部分超过1次,我必须确定,名称是相同的。所以我的问题是:是否有可能删除每个片段?这样每个片段都会移除自己而父母无所事事?

感谢您的帮助

编辑:

    MyFragment myFragment1 = new MyFragment();

    Bundle bundle = new Bundle();
    bundle.putInt("layout",R.layout.my_fragment);
    myFragment1.setArguments(bundle);

    getFragmentManager().beginTransaction()
            .replace(R.id.frameContainer, myFragment1)
            .addToBackStack(null)
            .commit();

这些电话我是从不同的地方做的。对于每个调用,我可以使用不同的片段创建自己的xml。 在我的父母Fragment中,我正在这样做:

    int layoutId = this.getArguments().getInt("layout", 0);
    if(layoutId==0)
        throw new RuntimeException("LayoutId not found");

    return inflater.inflate(layoutId,container,false);

在这之后,我的片段加载了xml,其中包含我在xml中设置的所有片段。那么我可以从外部定义视图。在从这个片段中销毁并重新打开之后,它将抛出错误。这是因为我的xml中的所有片段都没有被破坏!我的父片段不知道,哪些片段在xml中,所以我想,他们在课堂上摧毁自己。

1 个答案:

答案 0 :(得分:2)

发生此错误是因为只能创建子Fragment和&amp;以编程方式显示。 Fragment的XML布局不能包含<fragment ... />标记。来自docs

You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically.

以下是您需要做的事情:

第1步:修改父Fragment的XML布局,如下所示:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="230dp">

    <!-- <fragment
        android:id="@+id/myFragmen1"
        android:name="com...widgets.myViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" /> -->

    <FrameLayout
        android:id="@+android:id/childfragmentregion"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="0dp"
        android:layout_weight="1" >
    </FrameLayout>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/text""/>

</RelativeLayout>

第2步:然后,用于交换新的子片段:

FragmentManager fm = getChildFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.childfragmentregion, new SomeXYZFragment(), "some_xyz_fragment");
ft.commit();

第3步:覆盖您的父Fragment onDetach()方法,如下所示:

@Override
public void onDetach() {
    super.onDetach();

    try {
        Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
        childFragmentManager.setAccessible(true);
        childFragmentManager.set(this, null);

    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

这将无例外地工作。我请求您澄清问题的第二部分:我不清楚哪个Fragment正在Bundle中获取数据。如果你说得更清楚,我可以帮助你。