【问题标题】:How to pop back stack for Activity with multiple Fragments?如何为具有多个片段的 Activity 弹出堆栈?
【发布时间】:2012-01-07 20:36:21
【问题描述】:

假设我有一个 Activity,其中包含两个 FrameLayout(我们称它们为 FrameA 和 FrameB),而 每个 又包含一个 Fragment(我们分别称它们为 FragmentA1 和 FragmentB1)。现在,我使用类似于以下的代码提交一系列单独的片段事务...

getFragmentManager()
 .beginTransaction()
 .replace(frameId, fragment)
 .addToBackStack(null)
 .commit();

...这样我将FrameA中的FragmentA1替换为FragmentA2,然后将FrameB中的FragmentB1替换为FragmentB2,然后将FrameA中的FragmentA2替换为FragmentA3,然后将Frame2中的FragmentB2替换为FragmentB3,最终状态看起来像上图(只有 FragmentA3 和 FragmentB3 可见)。

如果我正确理解后退堆栈的工作原理,按“后退”将在 FrameA 和 FrameB 之间交错弹出片段(反映我添加它们的方式)。

有谁知道是否可以选择性地弹出 FrameA 或 FrameB 上的最后一个事务? (即,如果我按下“Pop FrameA”,那么 FrameA 将从 FragmentA3 转换回 FragmentA2,相反,如果我按下“Pop FrameB”,那么 FrameB 将从 FragmentB3 转换回 FragmentB2)

补充:我知道我可以使用FragmentManager.findFragmentById(int framelayoutId) 方法获取最后添加到给定FrameLayout 的Fragment,但是调用FragmentTransaction.remove(fragment).commit() 只会从View 中移除Fragment 而不会转换View返回之前显示的 Fragment。

【问题讨论】:

  • 如果 FragmentTransaction.remove “只从视图中移除 Fragment 而不会转换视图”,那么视图中显示的是什么?但是我可以理解为什么如果 Mgr 保留一堆碎片但不知道哪些碎片同时可见,这会导致混乱,即,当 B2 可能在它们之间时,它怎么知道 A2 在 A3 的“下方”堆栈?
  • 如果一个视图(在我的例子中是 FrameLayout)已经使用 FragmentTransaction.add(int, Fragment) 方法添加了多个 Fragment,然后调用 FragmentTransaction.remove(Fragment).commit() 我相信会留下 FrameLayout 显示最后添加到它的 Fragment。但是,使用FragmentTransaction.replace(int, Fragment) 方法将片段添加到视图(正如我正在做的那样,假设这对内存更好?!)将使 FrameLayout 没有子级(即显示为空视图)...
  • 补充我之前的评论:我可以看到有一些有用的方法,如FragmentManager.getBackStackEntryAt(int index)FragmentManager.popBackStack(String name, int flags)popBackStack(int id, int flags)FragmentTransaction.addToBackStack(String name)FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag),只是不知道如何合并他们一起实现我的要求......
  • 这正是我的问题,我仍在寻找答案......

标签: android android-fragments


【解决方案1】:

基本上,没有,一个活动只有一个回栈。

您只需要实现自己的独立后退栈。

从 Android 4.0(和相关的支持库)开始,有一些 API 可以让这变得相对容易——FragmentTransaction.detach(Fragment) 允许您将片段置于与在后堆栈中时相同的状态,FragmentManager.saveFragmentInstanceState(Fragment) 允许你走得更远,完全扔掉 Fragment 对象。并非巧合,它们分别用于实现 ViewPager 的 FragmentPagerAdapter 和 FragmentStatePagerAdapter,因此您可以查看它们的代码作为如何使用它们的示例。

【讨论】:

  • 感谢 Hackbod 的回复。我必须在我所知道的方面取得进展,因此实施了一个解决方案,我在 添加(而不是替换)片段 A2 之前隐藏片段 A1,然后显示 Fragment A2 被移除时再次显示Fragment A1。它对我有用,但肯定会像您在未来项目中描述的那样实现我自己的后台堆栈,或者如果当前项目中出现任何不希望的行为:-\再次感谢。
【解决方案2】:
FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

这里是最简单的答案,解释也很清楚:Well there are a few ways to go about this depending on the intended behavior, but this link should give you all the best solutions and not surprisingly is from Dianne Hackborn...

【讨论】:

  • 这如何回答这个问题?问题是关于选择性地弹出后堆栈的交错部分,而不是将后堆栈中的所有内容弹出回某个点(这是popBackStack()所做的)。
  • 另外,这里的链接指向一个问题,而不是一个答案。那里的问题有几个不同的答案,而不是一个明确的答案。也许您指的是 Joachim 接受的答案? (stackoverflow.com/a/5984892/423105)
  • @LarsH 您的建议更准确,所以我更正了正确答案的链接,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 2019-08-08
  • 1970-01-01
  • 2022-06-15
  • 2016-12-15
  • 2020-04-12
  • 1970-01-01
相关资源
最近更新 更多