【问题标题】:Preloading a fragment when popBackStackpopBackStack 时预加载一个片段
【发布时间】:2015-02-18 10:34:35
【问题描述】:

我对 backstack 行为有疑问。这就是我正在做的:

add(fragment1) + addToBackStack(null)
replace(fragment2) + addToBackStack(null)

发生了什么:

  • 片段 1 已添加并在后台堆栈中
  • 然后第二个片段替换第一个片段并添加到后台堆栈中。

现在我想用一个新的事务来更改我的最后一个 backstacked 片段,该事务放置一个新的 backstack 片段,所以:

[frag1, frag2] becomes [frag1, frag3]

但是popBackStack + replace 进行的此事务正在通过调用onCreateViewonActivityCreated 来加载frag1。我知道这是预期的行为,因为这是 backstack 的工作方式,但我正在尝试找到一种方法来避免这种预加载。

编辑

在这个问题中,我使用 backstack 片段的概念来使交易更加清晰。这里的每笔交易都是一个添加+删除(这是一个替换)。 我正在使用的替换代码是:

public int replaceFragment(BaseFragment newFragment, boolean addToBackStack, boolean animated, PopStackMode popMode) {
    if (popMode != null) {
        getSupportFragmentManager().popBackStack(newFragment.getFragmentTag(), popMode == PopStackMode.POP_INCLUSIVE ? FragmentManager
                .POP_BACK_STACK_INCLUSIVE : 0);
    }
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (animated) {
        ft.setCustomAnimations(R.anim.slide_in_left, 0, R.anim.slide_out_right, 0);
    }
    ft.replace(R.id.fragment_container, newFragment, newFragment.getFragmentTag());
    if (addToBackStack) {
        ft.addToBackStack(newFragment.getFragmentTag());
    }
    return ft.commit();
}

您可以看到我正在创建基于片段 backstack 的导航历史记录,因为它是一种浏览器。当添加一个“页面”时,会有一个片段和一个 backstack 事务。在这种情况下,我试图:

  • 删除当前片段。
  • 从后台删除事务。
  • 添加一个新片段而不弹出和加载前一个回栈片段。

我希望它更清楚。

编辑 2

我已经为支持此行为的标志填写了请求功能。找到它here

【问题讨论】:

  • 您可以使用嵌套片段在您可能希望篡改的每个后堆栈层分配一个容器片段,并只需更改子片段。
  • 除非听起来不错,否则如果您替换容器中父级的视图并将事务添加到后台堆栈会发生什么?它将像现在一样重新创建视图。我需要在用于导航的容器之上添加一个新容器以添加此行为。不是吗?
  • 我没有真正理解你的问题,但是嵌套的子替换不应该添加到后堆栈中。容器本身将是后栈上的一层,而子容器将是可动态替换的(不会篡改后栈)。

标签: android android-fragments fragment-backstack


【解决方案1】:

首先,您应该了解backstack 不保存片段,而是保存transactions。当您调用popBackStack 时,它实际上所做的是恢复以前的transaction。更多关于这个here

我认为你可以这样做:

  1. 通过为您的addToBackStack 提供唯一名称而不是 null 来命名您的交易。即addToBackStack("frag1")
  2. 不要打电话给popBackStack + replace,而是直接打电话给replace
  3. 然后,在你的活动中,覆盖你的onBackPressed,如果当前显示的片段是Frag3(如果你在replace方法中提供了标签,你可以使用findFragmentByTag检查这个)你可以调用getSupportFragmentManager().popBackStackImmediate("frag1", FragmentManager.POP_BACK_STACK_INCLUSIVE); (否则请致电super.onBackPressed

【讨论】:

  • 据我所知,这是行不通的,因为如果我不调用 popBackStack,此事务将保留在那里。我的要求并不比 2 个 frament 简单,那里可以有 7 个不同的片段。我实际上是在分配一个名称(片段类的规范名称)。请看一下我真正用于替换的代码,我编辑了答案。
  • 你是对的,事务将保留在那里,但是因为你为 popBackStack 方法提供了一个名称,正如你在 documentation 中看到的那样,它会弹出每个事务直到找到您提供的那个。无论如何,既然您承认您正试图从预期的行为中解决问题,我建议您重新考虑您的解决方案。
  • 问题出在需求本身。只有一个活动,使用片段导航。这太可怕了,但这就是他们想要的。所以我可以假设没有办法避免加载前一个交易或获取所有交易,弹出所有交易并重新添加所有交易,除了我讨厌的交易
  • 您可以在离开片段后向片段添加一个参数,然后检查该参数是否存在于 onCreateView 中,但这是一个丑陋的解决方法。
  • 当然,这太可怕了:(无论如何我认为它应该是一个标志,以避免在你制作 popBackStack 时预加载片段。也许我会在平台上填充一个功能,不应该很难添加它,因为他们现在有一个标记的流行音乐。
猜你喜欢
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
相关资源
最近更新 更多