【问题标题】:Remove fragment from backstack issue从 backstack 问题中删除片段
【发布时间】:2015-08-31 19:02:06
【问题描述】:

我有 4 个片段,标签分别为 Fragment1、Fragment2、Fragment3 和 Fragment4。

我在屏幕中添加了片段(1..4):

public void addFragment(Fragment fragment, String tag) {
   FragmentTransaction transaction = fragmentManager.beginTransaction();
   transaction.replace(myLayoutId, fragment, tag);
   transaction.addToBackStack(tag);
   transaction.commit();
   fragmentManager.executePendingTransactions();
}

如何从 backstack Immediate 中删除 Fragment2 和 Fragment3?

场景 1

getSupportFragmentManager().popBackStackImmediate(Fragment2, FragmentManager.POP_BACK_STACK_INCLUSIVE);

此代码删除了 Fragment2、Fragment3、Fragment4。

场景 2

getSupportFragmentManager().popBackStackImmediate(Fragment3, 0);
getSupportFragmentManager().popBackStackImmediate(Fragment2, 0);

此代码为 Fragment3 和 Fragment2 调用 onCreateView(为什么?!)。但是 Fragment 4 已经被移除,Fragment2 是可见的。

即我要:

  1. 添加 Fragment1、Fragment2、Fragment3、Fragment4

  2. 执行方法 removeFragments(Fragment2, Fragment3) 并且应该删除此片段。 onCreateView 不得被执行。删除后我需要有 Fragment1 和 Fragment4

  3. 按一次后退按钮:Fragment4 应该在没有 onCreateView 的情况下移除 Fragment4,Fragment1 应该是可见的。

【问题讨论】:

    标签: android android-fragments android-support-library


    【解决方案1】:

    一件重要的事情:在后台你没有片段,你有从一个片段到另一个片段的转换。这意味着堆栈看起来像:

    replace Fragment3 with Fragment4
    replace Fragment2 with Fragment3
    replace Fragment1 with Fragment2
    

    当您弹出 backstack 时,最顶层的转换被还原。您想要实现的是在后台 replace Fragment1 with Fragment4 上,因此当您还原它时,您将直接从 Fragment4 跳转到 Fragment1。为此,您需要弹出堆栈直到到达 Fragment1,然后插入 Fragment4,例如,当您从 3 变为 4 时,您可以

    getSupportFragmentManager().popBackStackImmediate(Fragment2, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    transaction.replace(myLayoutId, fragment4, tag).addToBackStack(tag).commit();
    

    还有一个remove 转换,但我认为它只有在您添加片段而不是替换它们时才有效(不确定,但非常肯定的是,当您按下后退按钮时它会引发异常......)

    【讨论】:

      【解决方案2】:

      为此,您应该覆盖onBackPressed

      onBackPressed 中,如果片段 4 处于活动状态,则应调用此函数,否则调用 super.onBackPressed()

      getSupportFragmentManager().popBackStackImmediate(Fragment2, FragmentManager.POP_BACK_STACK_INCLUSIVE);
      

      所以问题只归结为如何知道 Fragment 4 是否处于活动状态,

      1. 使用FragmentManager.findFragmentByTag(),我可以看到你已经为你的片段添加了标签,你可以尝试搜索Fragment4,如果它返回不为null,那么Fragment 4是活动的,假设你只有这4个Fragment
      2. 我更喜欢这种方法,只需保留一个 Fragment 处于活动状态的变量,您可以在 addFragment 中更新它。小心,记得把它保存在onSaveInstanceState

      编辑:

      另一种解决方案是在添加 Fragment4 之前立即调用 popBackStackImmediate(Fragment2, FragmentManager.POP_BACK_STACK_INCLUSIVE);,但这可能会触发不需要的动画,但您可能必须尝试知道。

      【讨论】:

      • 好的。我有超过 20 个不同片段的平板电脑应用程序。我应该手动管理所有片段吗?我认为,这不是一个好主意。 findFragmentByTag 始终返回已删除的片段,但不返回 null。嗯...
      • 那么 onSaveInstance 中的变量呢?对或错?在 onRestoeSavedInstance 中我应该手动恢复我的片段链吗?
      • 从你的原帖来看,我想你只有一个活动片段,如果是这样,你只需要一个变量来维持状态,从而恢复一个变量。
      • 我的左侧片段带有功能列表,右侧片段带有内容,内容片段可以包含任何片段。即 - 最少两个和最多 - 五个活动片段。
      • 添加了另一种方式,但我仍然认为保持状态应该更好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多