Android onConfigurationChanged:如何保存和恢复片段后退堆栈?

8
我有一个带有双面板的活动:左边是菜单项列表(片段 M),右边是当前选择项的详细信息(片段 D)。
当用户在片段 D 中选择一个项目时,片段 D 会被另一个片段替换(我们称之为 D1)。当用户在片段 D1 中选择一个项目时,片段 D1 会被另一个片段替换(我们称之为 D2),以此类推。当然,当用户按下返回按钮时,她可以回到片段历史记录中:D2->D1->D。
我的问题是:如何在配置更改(特别是屏幕方向)时保存和恢复完整的片段回退堆栈?
对我来说很奇怪,没有人在之前遇到过这个问题,但是我在谷歌和 Stack Overflow 上搜索时没有找到任何相关的帖子。如果我错过了任何相关的帖子,请指出来。
我知道我可以简单地将 android:configChanges="orientation|screenSize" 属性添加到我的活动中,以避免活动重新创建,但我无法这样做。
我不能这样做的原因是,我正在使用 Action Bar Sherlock(vers. 4)进行向后兼容,该组件需要在配置更改时重建活动才能正确工作,据我所知。
如果有另一种方法可以重新创建Action Bar Sherlock组件而不破坏和重新创建活动,请告诉我。
提前致谢。
2个回答

5
我能够通过将Fragments缓存到自己的ArrayList中来达成这个目标。然后,我设置了一个OnBackStackChangedListener来跟踪显示哪一个Fragment,并在必要时弹出ArrayList。
我的目的有点不同,但下面的代码应该是你所描述的需要的。标签可以让你拥有多个返回栈(back stacks),如果需要的话。它不能直接编译(因为我删掉了很多自己的代码),但应该能给你一个想法。额外的免责声明:我刚刚让它正常工作,可能还存在未发现的问题。
   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);
 }

希望这可以帮到你。

我对这种方法非常感兴趣,但是我觉得你的回答没有足够的细节让我轻松理解。你能在回答中添加更多细节吗? - deepwinter

0

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


1
@Iarham1 感谢您的回复,但是很遗憾,ABS 4 在某些操作系统版本(例如2.3.7)上仍存在一些问题,当设置android:configChanges="orientation"时,如[问题#279](https://github.com/JakeWharton/ActionBarSherlock/issues/279#issuecomment-4934511)所述。因此,目前这不是一个可行的解决方案。 我希望Jake Wharton能在不久的将来修复它,但与此同时,您或其他人是否知道如何在配置更改时保存和恢复完整的片段返回堆栈?或者替代方法是如何调整ABS代码以在配置更改时以编程方式重新创建仅ABS? - Luke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接