片段内的碎片
我想知道这是否是Android API中的一个错误:
我有一个像这样的设置:
┌----┬---------┐ | | | | 1 | 2 | | |┌-------┐| | || || | || 3 || └----┴┴-------┴┘
- 是在右窗格中加载片段#2(搜索屏幕)的菜单。
- 是包含片段#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.leftPane
和R.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();
在这里学习