当弹出整个FragmentManager BackStack时,初始片段未被渲染。

3
实际问题 / TL;DR: 除非使用我认为是一种hack的方法,否则我无法通过在onCreate()期间添加单个Fragment来弹出活动的整个backstack以返回到我的初始状态。该Fragment存在于Activity State Manager dump中,但不可见,导致屏幕为空白。
我今天遇到了这个问题,主要是想了解这是否是由于错误或对FragmentManager的BackStack的误解引起的。我希望确保我没有误用Fragments或在不稳定的API基础上构建。
我有一个活动,基本上提供一个下降的“树”导航,作为按钮网格,每个按钮打开子网格(例如具有更多按钮的子类别)或某些自定义表单。表单内容并不重要,但用户预计会以各种顺序反复填写它们。
我使用来自支持库(support-v4:25.1.1)的Fragments,每当需要新的“屏幕”时(无论是表单还是子网格),都会使用与活动的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时,遇到了非常奇怪的行为,这应该会将用户带回具有根网格(在上面的代码中添加的那个)的活动的初始状态。我尝试过的几乎所有技术都有效地清除了backstack,但却留下了一个空屏幕,而不是我的初始主菜单网格。在查看了多个问题和文档后,我尝试了多种解决方案,只有这个看起来像黑客的方法才起作用:
int remainingEntries = fragmentManager.getBackStackEntryCount();
while (remainingEntries-- > 0) {
    fragmentManager.popBackStackImmediate();
}

我认为这似乎是一种hack,因为它要求我立即(同步地)弹出任意数量的后退栈条目以到达根,而据我了解,应该可以通过单个异步方法调用来完成:

fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

或者,我在这里也看到过这个问题的解决方法:
int id = fragmentManager.getBackStackEntryAt(0).getId();
fragmentManager.popBackStack(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);

这只是root fragment的问题,可能是由于将其添加到视图的事务未添加到backstack,因为这将导致在用户按下返回按钮关闭活动时显示一个额外的空屏幕。
更多细节: -根据Activity State Manager dump,我的fragment仍然具有其视图,但mFragmentId和mContainerId均设置为#0。 -我确实添加了另一个保留其实例的fragment,但它仅用于保存一些数据,没有任何视图。

你正在使用的支持库版本是多少? - VishalKale
1个回答

1

支持库版本25.1.0及以上存在PopBackStackImmediate bug

由于已经有人报告了这个问题,你需要等待解决方案,或者降级支持库版本至25.0.1以获得预期的行为。

更新

看起来这个bug已经在支持库版本25.3.1中得到解决。请将您的库更新至版本25.3.1。


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