【问题标题】:Detect if fragment is truly visible in OnResume when being popped from backstack从后台弹出时检测片段是否在 OnResume 中真正可见
【发布时间】:2014-03-14 19:25:37
【问题描述】:

想象以下场景:

  1. 将片段 A 推送到 BackStack 上
  2. 将片段 B 推送到 BackStack 上
  3. 将片段 C 推送到 BackStack 上

片段 B 在调用其 onResume is 方法时尝试发出异步 Web 请求。

Fragment C 有一个名为“Clear Backstack”的按钮,它通过调用 popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) 来清除 backstack。

当调用 PopBackStackImmediate 时,它​​会一个一个地弹出 Fragments,直到堆栈被清除。当每个片段被弹出时,片段的 onResume 方法就会被调用。对于 Fragment B,我不希望触发异步 Web 请求,因为它会在弹出后立即被销毁/删除(因为正在清除整个后台堆栈)。

在这种情况下,如何检测整个 backstack 是否正在折叠并在 OnResume 方法中跳过 Fragment B 上的异步 Web 请求?注意:如果使用“后退”按钮弹出/显示片段 B,我仍然希望执行异步 Web 请求。

注意:我使用的是最新的兼容性/支持库。

【问题讨论】:

    标签: android fragment android-lifecycle onresume back-stack


    【解决方案1】:

    选项 1:

    您是否确定调用了哪些其他生命周期方法 - 如果它仅在恢复时,则将异步调用在生命周期中进一步向下移动(例如 onCreateView 或 onAttach),以便仅在以正常方式通过它时调用它.

    选项 2:

    当 onResume 被调用时,你可以对已经被销毁的片段执行 getFragmentByTag 。如果这是 null,那么您可以假设正在执行的操作是破坏。

    我觉得这个很丑。

    选项 3:

    让 C 将一些标志传递给控制活动(我们将其称为 Main),将异步调用向上移动,当 B 想要执行 Web 请求时,让它调用 main 来执行此操作。如果 C 设置了“I'm Destroying”标志,则不要执行请求。

    【讨论】:

    • 选项 #1 不起作用。我已经实现了类似于选项#3 的东西并且它工作正常,但我想知道是否有更简单的方法。如果没有更好的选择,我会暂时保留这个问题,并会接受你的答案。
    【解决方案2】:

    更新:我之前删除了旧片段,然后分别使用 FragmentTransaction.remove 和 FragmentTransaction.add 添加新片段。切换到 FragmentTransaction.replace 解决了我在使用 backstack 时遇到的大部分问题。见下文:

    Android 文档对 FragmentTransaction.replace 有这样的说法:

    替换已添加到容器中的现有片段。这本质上与为所有当前添加的片段调用 remove(Fragment) 相同,这些片段使用相同的 containerViewId 添加,然后使用此处给出的相同参数调用 add(int, Fragment, String)。

    我发现文档有点误导,因为当涉及到 backstack 时,replace 与 remove+add 之间存在重要区别:

    如果backstack A->B->C是用remove+add构建的,然后pop回到fragment A,那么会触发fragment B的onResume方法。 如果 backstack A->B->C 是用 replace 构建的,然后弹回到 Fragment A,则 Fragment B 的 onResume 方法不会被触发。

    【讨论】:

      猜你喜欢
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多