【问题标题】:Android onConfigurationChanged: how to save and restore fragment back stack?Android onConfigurationChanged:如何保存和恢复片段回栈?
【发布时间】:2012-04-03 18:45:27
【问题描述】:

我有一个带有双窗格的活动:左侧是菜单项列表(片段 M),右侧是当前所选项目的详细信息(片段 D)。

当用户在片段 D 中选择一个项目时,片段 D 会被另一个片段替换(我们称之为 D1)。当用户在片段 D1 中选择一个项目时,片段 D1 会被另一个片段(我们称之为 D2)替换,依此类推。 当然,当用户按下返回按钮时,她可以返回片段历史:D2->D1->D。

我的问题是:如何在配置更改时(特别是屏幕方向)保存和恢复完整的片段回栈?

对我来说似乎很奇怪,以前没有人遇到过这个问题,但是在我在 Google 和 Stack Overflow 上搜索时,我没有发现任何关于这个问题的信息。如果我错过了任何相关的帖子,请联系我。

我知道我可以简单地将android:configChanges="orientation|screenSize" 属性添加到我的活动中以避免重新进行活动,但我根本做不到。

我不能这样做的原因是我使用 Action Bar Sherlock(第 4 版)来实现向后兼容性,并且该组件需要重新创建活动才能在配置更改时正确运行,AFAIK。

如果有其他方法可以在不破坏和重新创建活动的情况下重新创建 Action Bar Sherlock 组件,请告诉我。

提前致谢。

【问题讨论】:

    标签: android onconfigurationchanged back-stack


    【解决方案1】:

    我可以通过缓存片段来做到这一点,因为我将它们添加到我自己的 ArrayList 中。然后我设置了一个 OnBackStackChangedListener 来跟踪显示的是哪一个,并根据需要弹出 ArrayList。

    我的目的有点不同,但下面的代码应该是您所描述的内容所需要的。标签是这样的,如果需要,您可以有多个后堆栈。它不会按原样编译(我已经剪辑了很多自己的代码),但应该让您了解我是如何做到的。附加免责声明:我刚刚完成了这项工作,可能还有一些我尚未解决的问题。

       public void replaceFragmentWithBackStackForTag(Fragment fragment, String tag)
       {
          FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
          ft.detach(visibleFragment);
          ft.add(R.id.realtabcontent, fragment, tag);
          ft.attach(fragment);
          ft.addToBackStack(null);
          manualBackStacks.get(tag).add(fragment);
          ft.commit();
          this.getSupportFragmentManager().executePendingTransactions();
       }
    

    在方向改变后重新创建活动的代码:

     ArrayList<Fragment> backStack =
           new ArrayList<Fragment>(manualBackStacks.get(tag));
     popArrayListToIndex(manualBackStacks.get(tag), 0); // helper I wrote
     for (int bs = 1; bs < backStack.size(); bs++) {
        replaceFragmentWithBackStackForTag(backStack.get(bs), tag);
     }
    

    后台监听器:

     public void onBackStackChanged() {
        int index = getSupportFragmentManager().getBackStackEntryCount();
        ArrayList<Fragment> backStack = manualBackStacks.get(tag);
        visibleFragment = backStack.get(index);
        // Pop the last element if we've backed up.
        popArrayListToIndex(backStack, index);
     }
    

    希望这会有所帮助。

    【讨论】:

    • 我对这种方法很感兴趣,但我觉得您的回答没有提供足够的细节让我很容易理解。您可以在答案中添加更多细节吗?
    【解决方案2】:

    Action Bar Sherlock (ABS) 需要重新创建操作栏作为 ABS 3.x 中重新创建活动的一部分,但根据@Jake Wharton's comment,版本 4 不需要重新创建 - 它可以处理方向更改。因此,设置 android:configChanges="orientation" 并且您的片段返回堆栈将持续存在。

    【讨论】:

    • @Iarham1 感谢您的回复,但不幸的是,当设置了 android:configChanges="orientation" 时,ABS 4 在某些操作系统版本(例如 2.3.7)上仍然存在一些问题,如@中所述987654322@,所以目前这不是一个可行的解决方案。我希望 Jake Wharton 会在不久的将来修复它,但是,与此同时,您或其他任何人是否知道如何在配置更改时保存和恢复完整的 Fragment Back 堆栈?或者如何调整 ABS 代码以在配置更改时以编程方式仅重新创建 ABS?
    猜你喜欢
    • 1970-01-01
    • 2015-10-06
    • 2013-04-04
    • 2014-04-25
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2011-10-12
    相关资源
    最近更新 更多