【问题标题】:How to delete a specific fragment from back stack in android如何从android中的后台堆栈中删除特定片段
【发布时间】:2015-09-20 19:52:47
【问题描述】:

我有一个关于从后台堆栈中删除特定片段的问题。我的场景是这样的。Fragment-1 被 Fragment-2 替换,然后 Fragment-2 被 Fragment-3 替换。

调用顺序; Fragment-1-->Fragment-2-->Fragment-3.

当 Fragment-3 在屏幕上然后单击返回按钮时,我想去

Fragment-1。这意味着我想从后台堆栈中删除 Fragment-2。

如何做到这一点?

【问题讨论】:

  • 可以轻松切换而不是删除Fragment.....

标签: android android-fragments fragment fragment-backstack


【解决方案1】:

在后台你没有Fragments,但是FragmentTransactions。当您popBackStack() 再次应用事务时,但会向后应用。这意味着(假设你每次都addToBackStackTrace(null))在你的后台你有

1->2
2->3

如果您不将第二笔交易添加到后台堆栈,结果是您的后台堆栈只是

1->2

因此按下后退按钮将导致2->1 的执行,由于片段2 不存在而导致错误(您在片段3 上)。
最简单的解决方案是在从 2 到 3 之前弹出 backstack

//from fragment-2:
getFragmentManager().popBackStack();
getFragmentManager().beginTransaction()
   .replace(R.id.container, fragment3)
   .addToBackStack(null)
   .commit();

我在这里做的是:从片段 2 我回到片段 1,然后直接回到片段 3。这样后退按钮会再次将我从片段 3 带到片段 1。

【讨论】:

  • 这不是我想要的确切解决方案。我必须在进入片段 3 时将片段 2 添加到后堆栈。在片段 3 中,取决于我想要删除片段 2 的条件从 backstack 没有任何动作然后点击后退按钮,只想去 fragment-1
  • @sahin 好的,那么这不是一个可行的选择...也许您可以尝试使用popBackStack (int id, int flags),但我没有尝试过,我不知道动画的行为...
  • 当您在从 2 到 3 系统尝试显示片段 1 之前弹出回栈时。每次弹出片段编号 N 时,它都会尝试显示片段编号 (N-1)。如果您强制转到片段 3,您将在 1 个片段的 onCreateView 期间获得 NPE...
  • @llario,感谢您的回答解决了我的问题。
  • @sunlover3 我在 Lollipop 上用过这个方法,四年半时间可能很多事情都变了……关于这个问题至少有一个问题,stackoverflow.com/questions/56539251/…我不在andorid开发了,帮不了你了,抱歉
【解决方案2】:

我的情况与您的情况非常相似,我的解决方案只是检查我拥有的 backStack 交易量。

如果交易超过 0,那么我会立即弹出它 所以它会在按下时跳过它。

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        getSupportFragmentManager().popBackStackImmediate();
}
...
fragmentTransaction.replace(R.id.main_fragment, newFrag, MAIN_FRAGMENT_TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();

这会成功:

  • A -> B(后按)-> 回到 A

  • A -> B -> C(后按)-> 回到 A

我看到的唯一缺点是在转到片段 C 之前显示片段 A 的快速闪烁。

【讨论】:

  • 像其他人建议的那样只调用.popStack() - 在我的情况下 - 导致视图在转到 C 后自动恢复到 A - 在按下后退按钮之前。此处列出的popBackStackImmediate() 对我的情况产生了影响,我现在有从 C 回到 A 的后退按钮 - 我遇到的其他答案都没有提到它。谢谢!
  • 请指定在哪里编写这段代码?我的意思是哪个片段。
【解决方案3】:

如果您在同一个活动中添加/启动所有三个片段,而不是add(),请使用replace()(将Fragment2 替换为Fragment3)。 replace 方法在添加新片段之前从 backstack 中删除当前片段。如果您从其他活动启动Fragment3,因此您不能使用replace(),请在开始新活动之前从后台删除Fragment2(这会添加Fragment3):

// in Fragment2, before adding Fragment3:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
               .remove(this) // "this" refers to current instance of Fragment2
               .commit();
fragmentManager.popBackStack();
// now go ahead and launch (add) fragment3
// if fragment3 is launched from a different activity, 
// start that activity instead
fragmentManager.beginTransaction()
               .add(R.id.a_container_view_in_activity, new Fragment3(),
                    Fargment3.FRAGMENT3_ID)
               .commit();

【讨论】:

    【解决方案4】:

    片段 A -> 片段 B 的代码:

    添加片段ABackStack的片段

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.frame_layout_container, new fragmentB());
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();
    

    片段 B -> 片段 C 的代码:

    不要在 BackStack 的 Fragments 中添加 Fragment B

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.frame_layout_container, new fragmentC());
    fragmentTransaction.commit();
    

    它将以这种方式工作:A -> B -> C 并且 返回 C-> A 如你所不。

    希望对你有所帮助。

    【讨论】:

    • 再要B->A就不能用了
    【解决方案5】:

    您从FragmentTransaction 添加到后台状态并使用FragmentManager pop 方法从后台删除:

    FragmentManager manager = getActivity().getSupportFragmentManager();
    FragmentTransaction trans = manager.beginTransaction();
    trans.remove(myFrag);
    trans.commit();
    manager.popBackStack();
    

    您只需将片段从添加到片段堆栈中跳过,这样当您从Fragment-3回来时,它就会回到Fragment-1

    更新:

    要禁用动画,需要重写onCreateAnimation方法...

    @Override
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
        if (disableAnim) {
            Animation a = new Animation() {};
            a.setDuration(0);
            return a;
        }
        return super.onCreateAnimation(transit, enter, nextAnim);
    }
    

    【讨论】:

    • 第二个选项(从添加到堆栈中跳过片段)不起作用,我在回答中解释了它...第一个看起来不错,而且可能比我的 ^^
    • manager.popBackStack 正在动画片段。我不想这样做。在片段 3 中,如何在屏幕上不进行任何操作的情况下删除片段 2,然后单击返回按钮时只想去片段 1。
    • Kartheek,我没有使用支持 v4,这意味着我有 Fragment 的 onCreateAnimator 方法而不是 onCreateAnimation。
    【解决方案6】:
       for (int i = 0; i < mFragmentManager.getBackStackEntryCount(); i++) {
            currentFragment = mFragmentManager.getFragments().get(i);
            if (!(currentFragment instanceof ParticularFragment))
                mFragmentManager.popBackStack();
            else
                break;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 2016-12-15
      • 2019-03-20
      • 2012-12-16
      相关资源
      最近更新 更多