【发布时间】:2017-03-02 22:07:23
【问题描述】:
实际问题/TL;DR:除非使用一种我认为是 hack 的方式,否则我无法通过在 onCreate() 期间添加的单个片段弹出活动的整个后台堆栈以返回到我的初始状态。 Fragment 存在于活动状态管理器转储中,但不可见,让我的屏幕为空。
我今天遇到了这个问题,主要是想了解这是由于错误还是我对 FragmentManager 的 BackStack 的误解引起的。我想确保我没有滥用 Fragments 或建立在摇摇欲坠的 API 基础上。
我有一个活动,它基本上提供了一个下降的“树”导航作为按钮网格,其中每个按钮打开一个子网格(例如,具有更多按钮的子类别)或一些自定义表单。表单的内容无关紧要,但希望用户在各种订单中重复填写。
我使用来自支持库 (support-v4:25.1.1) 的 Fragments,每当需要新的“屏幕”时(无论是表单还是子网格),都会使用 Activity 的 FragmentManager 上的事务添加它类似于:
/* adding a new screen, going further down our nav tree */
fragmentManager
.beginTransaction()
.addToBackStack("...")
.replace(R.id.container, newFragment)
.commit();
除了我的活动初始状态的设置之外,每个事务看起来都是这样的,它添加了初始“根网格”片段而不将事务添加到后台状态。
/* adding the initial fragment during the first execution of activity's onCreate(). */
fragmentManager
.beginTransaction()
.replace(R.id.container, rootFragment)
.commit();
我在这里发帖的原因是我在尝试弹出整个 BackStack 时遇到了一个非常奇怪的行为,这应该使用户回到具有根网格的活动的初始状态(添加的那个在上面的代码中)。几乎我尝试过的每一种技术都能有效地清除后台堆栈,但留下一个空白屏幕而不是我最初的主菜单网格。在查看了这里的多个问题和文档后,我尝试了多种解决方案,但只有这个看起来很黑客的解决方案有效:
int remainingEntries = fragmentManager.getBackStackEntryCount();
while (remainingEntries-- > 0) {
fragmentManager.popBackStackImmediate();
}
我说这似乎是一种 hack,因为它需要我立即(同步)弹出任意数量的 backstack 条目以到达根目录,而据我了解,它应该可以做到这一点单个异步方法调用:
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
或者正如我在这里看到的那样:
int id = fragmentManager.getBackStackEntryAt(0).getId();
fragmentManager.popBackStack(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);
这只是根片段的问题,可能是因为将它添加到视图的事务没有添加到后台堆栈,因为这会导致当用户按下后退按钮关闭时显示额外的空白屏幕活动。
更多细节:
- 根据活动状态管理器转储,我的片段仍然有它的视图,但 mFragmentId 和 mContainerId 都设置为 #0。
- 我确实添加了另一个我没有在这里讨论过的片段,它保留了它的实例,但它只用于保存一些数据并且没有任何视图。
【问题讨论】:
-
你使用的支持库是什么版本的?
标签: android android-fragments fragment-backstack