碎片中的碎片

Gra*_*eme 145 android android-fragments android-nested-fragment

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

我有这样的设置:

?----?---------?
|    |         |
|  1 |    2    |
|    |?-------?|
|    ||       ||
|    ||   3   ||
?----??-------??
Run Code Online (Sandbox Code Playgroud)
  1. 是一个在右侧窗格中加载片段#2(搜索屏幕)的菜单.
  2. 是包含片段#3的搜索屏幕,片段#3是结果列表.
  3. 结果列表在几个地方使用(包括作为一个功能正常的高级片段).

此功能在手机上非常有效(其中1和2和3为ActivityFragments).

但是,当我使用此代码时:

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

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

据我所知,上面的代码删除了驻留的片段,然后用新的片段替换它.很棒......显然不会发生这种情况,因为当第二次运行此代码时会出现以下异常:

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
Run Code Online (Sandbox Code Playgroud)

这是因为FragmentNumber3的容器已被复制,并且它不再具有唯一ID.在添加新的片段之前,初始片段没有被销毁(?)(在我看来,这意味着它还没有被替换).

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

hac*_*bod 202

目前不支持嵌套片段.试图将片段放在另一个片段的UI中将导致未定义且可能破坏的行为.

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

注意(根据本文档):" 注意:当布局包含a时,不能将布局扩展为片段<fragment>.只有在动态添加到片段时才支持嵌套片段. "

  • 不支持,因为它不是初始实现的设计目标.我听过很多关于这个功能的请求,所以它可能会在某些时候完成,但是像往常一样,还有许多其他的东西在优先级上与它竞争. (14认同)
  • 现在这一点.嵌套的`Fragment`s现在是Android API的一部分,是的!http://developer.android.com/about/versions/android-4.2.html#NestedFragments. (11认同)
  • 哇,真是个噩梦:如果你在片段上使用<fragment>,并且Fragment碰巧使用子片段,它就不会因为明显错误而失败("无法将子片段添加到布局片段") - 它神秘地失败,例如"片段没有创建视图".有几个小时的时间调试...... (9认同)
  • @MartínMarconcini肯定,但根据API提供的功能,这根本不明显.如果不允许某些东西,*应该*清楚地记录下来,而不是留给开发人员将头发拉出来,因为某些东西没有按照你期望的方式工作. (6认同)
  • 我通过扩展FragmentActivity,FragmentManager和FragmentTransaction来管理它.基本前提是在我的活动中扩展DeferringFragmentActivity,提供相同的api,因此没有其他代码更改.当我调用getFragmentManager时,我得到一个DeferringFragmentManager实例,当我调用beginTransaction时,我得到一个DeferredTransaction.此事务使用被调用的方法和参数存储POJO.当调用commit时,我们首先查找任何挂起的DeferredTransactions.一旦提交了所有事务,我们就会启动一个真正的事务并使用args运行所有存储的方法. (4认同)
  • 由于错误或缺乏功能而不支持?这将在未来的版本中修复吗? (2认同)
  • ViewPager怎么样?它可以包含在片段中,并将其他片段显示为其子元素.看一下代码,很明显它实际上并没有在其他片段上插入片段,而是将它们添加到活动中,而是将片段视图放入其内部的ScrollView中.我们遇到了ViewPager,BTW的奇怪行为. (2认同)

Ran*_*med 98

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

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

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

Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();
Run Code Online (Sandbox Code Playgroud)

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

这是一篇SO帖子,讨论嵌套片段的最佳实践.

  • 花了将近半天的时间与撞车事故搏斗.终于找到了答案:)谢谢. (2认同)

小智 33

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

@Override
    public void onDestroyView() {

      try{
        FragmentTransaction transaction = getSupportFragmentManager()
                .beginTransaction();

        transaction.remove(nestedFragment);

        transaction.commit();
      }catch(Exception e){
      }

        super.onDestroyView();
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用SetAlwaysFinish(http://bricolsoftconsulting.com/2011/12/23/how-to-test-onsaveinstancestate-and-onrestoreinstancestate-on-a-real-device/)进行一些生命周期测试,您会看到当另一个活动进入顶部且始终完成启用时,此代码会导致错误(IllegalStateException:在onSaveInstanceState之后无法执行此操作).在try/catch中包含上面的代码并不是最优雅的解决方案,但它似乎使一切正常. (4认同)

dra*_*sia 14

我有一个我正在开发的应用程序,它与Action Bar中的Tabs类似,用于启动片段,其中一些片段中有多个嵌入的片段.

我试图运行应用程序时遇到了同样的错误.看起来如果在取消选中标签后再在xml布局中实例化片段,然后重新选择,我会得到充气机错误.

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

我希望这能够帮到你.