片段内的碎片

我想知道这是否是Android API中的一个错误:

我有一个像这样的设置:

┌----┬---------┐ | | | | 1 | 2 | | |┌-------┐| | || || | || 3 || └----┴┴-------┴┘ 
  1. 是在右窗格中加载片段#2(搜索屏幕)的菜单。
  2. 是包含片段#3的搜索屏幕,其是结果列表。
  3. 结果列表在几个地方被使用(包括作为一个正常运行的高级片段)。

这个功能在手机上工作得非常好(其中1&2和3是ActivityFragment )。

但是,当我使用这个代码:

  FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment frag = new FragmentNumber2(); if(toLoad != null) frag.setArguments(toLoad); transaction.replace(R.id.rightPane, frag); transaction.commit(); 

其中R.id.leftPaneR.id.rightPane在水平线性布局中<fragment>

这是我的理解,上面的代码中删除了驻留的片段,然后用新的片段替换它。 辉煌…显然这不是发生什么,因为当这个代码运行第二次你得到以下异常:

 07-27 15:22:55.940: ERROR/AndroidRuntime(8105): Caused by: java.lang.IllegalArgumentException: Binary XML file line #57: Duplicate id 0x7f080024, tag null, or parent id 0x0 with another fragment for FragmentNumber3 

这是因为FragmentNumber3的容器已被复制,并且不再具有唯一的ID。 在添加新的片段之前,最初的片段没有被破坏(在我的脑海中,这意味着它没有被替换 )。

有人可以告诉我,如果这是可能的( 这个答案表明它不是)或者是一个错误?

目前不支持嵌套片段。 试图在另一个片段的用户界面中放置一个片段将导致未定义的,可能的破坏行为。

更新 :Android 4.2(和Android支持库第11版)支持嵌套片段: http : //developer.android.com/about/versions/android-4.2.html#NestedFragments

注意 (按照本文档 ):“ 注意:当布局包含一个<fragment>时,不能将布局膨胀成一个片段,只有在动态添加到片段时才支持嵌套片段。

Android 4.2及更高版本支持嵌套片段

Android 支持库现在也支持嵌套片段 ,因此您可以在Android 1.6或更高版本上实现嵌套片段设计。

要嵌套一个片段,只需在要添加片段的片段上调用getChildFragmentManager()即可。 这将返回一个FragmentManager,您可以像使用顶级活动一样使用FragmentManager来创建片段事务。 例如,下面是一些在现有的Fragment类中添加片段的代码:

 Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit(); 

要了解嵌套片段的更多信息,请阅读这些教程
第1部分
第2部分
第3部分

这里是讨论嵌套片段最佳实践的SO帖子。

..你可以在父段的destroyview方法中清理你的嵌套片段:

 @Override public void onDestroyView() { try{ FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); transaction.remove(nestedFragment); transaction.commit(); }catch(Exception e){ } super.onDestroyView(); } 

我有一个应用程序,我正在开发的,与操作栏中的标签类似,启动片段,其中一些片段有多个嵌入片段。

我试图运行应用程序时遇到了同样的错误。 看起来好像如果你实例化的选项卡之后xml布局的碎片然后重新选择,我会得到充气机错误。

我解决了这个问题,用Linearlayouts替换xml中的所有片段,然后使用片段管理器/片段事务实例化片段,至少在测试级别上,所有东西似乎都能正常工作。

我希望这可以帮助你。

我面临同样的问题,已经挣扎了几天,应该说,最简单的方法来克服我发现这是使用fragment.hide()/ fragment.show()当选项卡被选中/未选中()。

 public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { if (mFragment != null) ft.hide(mFragment); } 

当屏幕旋转发生时,所有父级和子级碎片都被正确销毁。

这种方法还有一个好处 – 使用hide()/ show()不会导致片段视图松散其状态,因此不需要为ScrollViews恢复以前的滚动位置。

问题是,我不知道在不可见的时候不要拆分碎片是否正确。 我认为TabListener的官方例子是考虑到碎片是可重用的,不应该污染他们的内存,但是,我想如果你只有几个选项卡,你知道用户将频繁地切换它们将适合于保持他们与当前的活动。

我想听听更有经验的开发人员的意见。

如果你发现你的嵌套片段不被删除或重复(例如,在Activity重新启动,在屏幕上旋转)尝试改变:

 transaction.add(R.id.placeholder, newFragment); 

 transaction.replace(R.id.placeholder, newFragment); 

如果上面没有帮助,请尝试:

 Fragment f = getChildFragmentManager().findFragmentById(R.id.placeholder); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); if (f == null) { Log.d(TAG, "onCreateView: fragment doesn't exist"); newFragment= new MyFragmentType(); transaction.add(R.id.placeholder, newFragment); } else { Log.d(TAG, "onCreateView: fragment already exists"); transaction.replace(R.id.placeholder, f); } transaction.commit(); 

在这里学习