【问题标题】:No view found for id when popping backstack without adding to backstack在未添加到后台堆栈的情况下弹出后台堆栈时找不到 id 的视图
【发布时间】:2015-08-18 04:45:16
【问题描述】:

我正在开发一个 Android 应用程序,遇到了涉及 Fragments 和 FragmentTransactions 的错误。我创建了一个示例应用程序来演示该问题。这是我正在做的事情:

  1. add Fragment1fragmentSpace,无需添加到后台堆栈。
  2. replace fragmentSpaceFragment2,以 "beginning" 的形式添加到后台。
  3. add Fragment3fragmentSpace2(在 Fragment2 内部),不添加到 backstack。
  4. replacefragmentSpace2Fragment4,以 null 的形式添加到后台堆栈。
  5. 调用 getFragmentManager().popBackStack("beginning", FragmentManager.POP_BACK_STACK_INCLUSIVE); 以尝试撤消所有事务,这将使用户恢复为只能看到 Fragment1

但是,应用程序在第 5 步崩溃并出现以下错误:

java.lang.IllegalArgumentException: No view found for id 0x7f090004 (me.MitchT.testfragmenttransactions:id/fragmentSpace2) for fragment Fragment3{7f35cb6 #2 id=0x7f090004}
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:886)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:1645)
...

我发现如果我将第 3 步添加到 backstack,第 5 步不再使应用程序崩溃,也不会再出现错误。为什么?

将第 3 步添加到后台堆栈时遇到的问题是,我希望用户能够在添加 Fragment3 后按下后退按钮并返回到 Fragment1。如果我将它添加到后台堆栈,那么当用户按下后退按钮时,它会删除Fragment3,但Fragment2 仍然可见,因此他们必须再次按下后退按钮。我试图避免这种双后退按钮行为。

我觉得没有必要在这个问题的示例应用中发布每个文件的代码,所以我创建了一个gist.

所以我想我的问题是:

  1. 为什么会出现此错误?
  2. 为什么我在将第 3 步添加到后台堆栈后没有收到错误消息?
  3. 有没有更好的“回到起点”或一次返回两个片段的方法?

谢谢!

【问题讨论】:

  • 没有找到id开头的视图。只需使用popbackstack()

标签: android android-fragments fragmenttransaction fragmentmanager


【解决方案1】:

据我了解。您有一个片段布局,它是活动中的容器

Activity 承载 Fragment1。然后将 Fragment 1 替换为 Fragment 2(添加到后堆栈。

在此阶段单击返回按钮,您将弹出 fragment2,您会看到托管 fragment1 的活动。

Fragment2 有一个包含 fragment3 的框架布局。然后你有 Fragment4 替换 Fragment3 被添加到后台堆栈。

现在单击您拥有的按钮getFragmentManager().popBackStack("beginning", FragmentManager.POP_BACK_STACK_INCLUSIVE);。但是没有具有该 ID 的视图。

只需使用popBackStack()。 Fragment4 --> Fragment2(托管fragment3)--> Fragment1(由活动托管)。

如果您希望 Fragment4 到 Activity 托管 Fragment1,请不要将 Fragment4 添加到后台堆栈。

注意:如果你想要嵌套片段,你需要使用getChildFragmentManager()https://developer.android.com/about/versions/android-4.2.html

还要注意 cmets 部分的讨论以及 op Is this the right way to clean-up Fragment back stack when leaving a deeply nested stack? 发布的链接

【讨论】:

  • 在第 2 步中,我将添加到 backstack 作为“开始”:gist.github.com/MitchTalmadge/… 不应该从中找到吗?
  • @MitchTalmadge 但堆栈中有 fragment4。
  • @MitchTalmadge 还注意到,fragment2 在 backstack 中,fragment3 和 4 由 Fragment 2 托管。
  • 谢谢,我使用 popBackStack 做了一个 for 循环,解决了这个问题。但是,我仍然不明白 backstack 如何找不到“开始”。特别是在阅读了这个问题的答案之后:stackoverflow.com/questions/5802141/… 我的理解是 popBackStack(String, int) 基本上会做 popBackStack() 直到它到达具有指定标签的事务。
  • 哎呀!那解决了它!非常感谢!!我不知道 getChildFragmentManager(),这对我来说更有意义。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 2016-01-26
  • 2012-01-04
  • 2015-09-30
  • 1970-01-01
相关资源
最近更新 更多