我有一个片段,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中,所以我想,他们在课堂上摧毁自己。
答案 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
中获取数据。如果你说得更清楚,我可以帮助你。