简体   繁体   English

弹出整个FragmentManager BackStack时不会呈现初始片段

[英]Initial Fragment not rendered when popping entire FragmentManager BackStack

Actual problem / TL;DR: Except when using one way I consider a hack, I can't pop the activity's entire backstack to return to my initial state with a single fragment added during onCreate(). 实际问题/ TL; DR:除了使用一种方法我认为是hack之外,我无法弹出活动的整个backstack返回到我的初始状态,在onCreate()期间添加了一个片段。 The Fragment is present in the Activity State Manager dump, but is not visible, leaving me with an empty screen. 片段存在于“活动状态管理器”转储中,但不可见,使我显示为空屏幕。

I have encountered this issue today and am mostly trying to understand whether this is caused by a bug or by my misunderstanding of the FragmentManager's BackStack. 我今天遇到过这个问题,主要是试图了解这是由错误还是由于我对FragmentManager的BackStack的误解造成的。 I want to make sure I'm not misusing Fragments or building on shaky API foundations. 我想确保我不会滥用碎片或在不稳定的API基础上构建。

I have an activity which essentially offers a descending "tree" navigation as a grid of buttons where each button opens either a sub-grid (eg sub-category with more buttons) or some custom form. 我有一个活动,基本上提供一个降序的“树”导航作为按钮网格,其中每个按钮打开子网格(例如具有更多按钮的子类别)或一些自定义形式。 The content of the forms is irrelevant, but users are expected to repetitively fill them in various orders. 表单的内容是无关紧要的,但是用户应该以各种顺序重复填写它们。

I use Fragments from the support library (support-v4:25.1.1) and whenever a new "screen" is required (either for a form or a sub-grid) it will be added using a transaction on the activity's FragmentManager similar to: 我使用支持库中的Fragments(support-v4:25.1.1),每当需要一个新的“屏幕”时(对于表单或子网格),它将使用活动的FragmentManager上的事务添加,类似于:

/* adding a new screen, going further down our nav tree */
fragmentManager
            .beginTransaction()
            .addToBackStack("...")
            .replace(R.id.container, newFragment)
            .commit();

Every transaction looks like that except the setup of the initial state of my activity, which adds the initial "root grid" fragment without adding the transaction to the backstate. 除了设置我的活动的初始状态之外,每个事务都是这样的,它添加了初始的“根网格”片段,而没有将事务添加到后台。

/* adding the initial fragment during the first execution of activity's onCreate(). */
fragmentManager
            .beginTransaction()
            .replace(R.id.container, rootFragment)
            .commit();

The reason I'm posting here is that I encountered a very strange behaviour when attempting to pop the entire BackStack, which is supposed to bring the user back to the initial state of the activity which has the root grid (the one added in the code above). 我在这里发帖的原因是我在尝试弹出整个BackStack时遇到了一个非常奇怪的行为,它应该将用户带回到具有根网格的活动的初始状态(代码中添加了一个)以上)。 Almost every technique I tried effectively clears the backstack, but leaves an empty screen instead of my initial main-menu grid. 我尝试的几乎所有技术都有效地清除了后台堆栈,但是留下了一个空屏幕,而不是我最初的主菜单网格。 After looking around on multiple questions here and the docs, I tried multiple solutions and only this hack-looking one has worked: 在查看了这里的多个问题和文档之后,我尝试了多个解决方案,只有这个看起来很黑的问题才有效:

int remainingEntries = fragmentManager.getBackStackEntryCount();
while (remainingEntries-- > 0) {
    fragmentManager.popBackStackImmediate();
}

I say this seems like a hack because it requires me to immediately (synchronously) pop an arbitrary number of backstack entries to reach the root, whereas from my understanding it should be possible to do that with a single asynchronous method call: 我说这看起来像是一个黑客,因为它要求我立即 (同步)弹出任意数量的backstack条目以到达根,而根据我的理解,应该可以通过单个异步方法调用来做到这一点:

fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

or as I've also seen posted around here: 或者我也看到过这里张贴的:

int id = fragmentManager.getBackStackEntryAt(0).getId();
fragmentManager.popBackStack(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);

This is only an issue with the root fragment, probably because the transaction which adds it to the view is not added to the backstack, since that would cause an extra empty screen to be shown when the user presses the back button to close the activity. 这只是根片段的一个问题,可能是因为将其添加到视图的事务没有添加到backstack,因为当用户按下后退按钮关闭活动时,这将导致显示额外的空屏幕。

More details: 更多细节:

  • According to the Activity State Manager dump my fragment still has its view, but has both mFragmentId and mContainerId set to #0. 根据活动状态管理器转储我的片段仍然有它的视图,但mFragmentId和mContainerId都设置为#0。
  • I do add another fragment I haven't discussed here which retains its instance, but it is only used to hold some data and has no view whatsoever. 我确实添加了另一个我没有在这里讨论的片段,它保留了它的实例,但它只用于保存一些数据并且没有任何视图。

There is a PopBackStackImmediate bug in support library version 25.1.0 and above. 支持库版本25.1.0及更高版本中存在 PopBackStackImmediate错误 Since this issue has been reported either you have to wait for solution, Or you can downgrade the support library version to 25.0.1 and get the expected behavior. 由于已报告此问题,您必须等待解决方案,或者您可以将支持库版本降级到25.0.1并获得预期的行为。

UPDATE UPDATE

Looks like this bug has been resolved in support library version 25.3.1 . 看起来这个bug已在支持库版本25.3.1中得到解决。 Update your library to version 25.3.1. 将库更新到版本25.3.1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM