0

我有一个片段,其中 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 是动态的。我通过包获取布局,所以在这个片段中我不知道显示的是哪个片段。如果我使用这部分超过 1 次,我必须确定名称是相同的。所以我的问题是:是否有可能删除每个片段中的 ?让每一个fragment都删除自己和parent无关?

感谢帮助

编辑:

    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。在我的父母片段中,我正在这样做:

    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 中,所以我想要它们在他们的班级中摧毁自己。

4

1 回答 1

2

发生此错误是因为 childFragment只能以编程方式创建和显示。a 的 XML 布局Fragment不能包含<fragment ... />标记。从文档

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.

这是您需要做的:

STEP 1:修改 parentFragment的 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 步:覆盖您 parentFragmentonDetach()方法,如下所示:

@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. 如果你说得更清楚,我可以进一步帮助你。

于 2014-06-23T10:13:34.823 回答