繁体   English   中英

Android从BackStack中删除片段和视图

[英]Android Remove Fragment and View from BackStack

在此输入图像描述

我知道之前已经问过这个问题,但是到目前为止我已经得到了以前的答案。 方案如下:我们有一个仪表板片段(A),它将用户引导到登录屏幕(B)。 成功登录后,他们会转到列表视图(c)。 在背压上我想返回A,因为用户不需要再次看到登录屏幕。 此外,在成功登录后,我们将详细信息存储在共享首选项中,并在下次自动登录B,这些都按计划运行。

我有以下FragmentHelper方法:

public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx)
    {
        // Create new fragment and transaction
        FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction();
        transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(container, fragment);

        if(addToBackStack)
            transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }

在从B到CI的事务中,将布尔addToBackStack设置为false,以便transaction.addToBackStack(null); 不叫。 这再次运作良好,但之后我的问题开始了。

当用户按下C并返回AI时,仍然可以在A的视图下看到C的膨胀视图。

任何帮助,将不胜感激。 我希望我的图表有助于保持这一点。

我解决了这个问题... ...

getFragmentManager().popBackStack();

要么

getSupportFragmentManager().popBackStack()

这在您添加片段和维护backstack(不替换)时有效。

f1 - > f2

Fragment2 f2 = new Fragment2();
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit();

这里没什么特别的。 在片段f2中,此代码将您带到片段f3。

f2 - > f3

Fragment3 f3 = new Fragment3();
getActivity().getSupportFragmentManager().popBackStack();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();

我不确定通过阅读文档,如果这应该工作,这个弹出的事务方法据说是异步的,也许更好的方法是调用popBackStackImmediate()。 但到目前为止,我可以在我的设备上告诉它它的工作完美无瑕。

所述替代方案将是:

final FragmentActivity activity = getActivity();
activity.getSupportFragmentManager().popBackStackImmediate();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();

这里实际上会有短暂的回到f1 beofre继续前进到f3,所以那里有轻微的故障。

这实际上是你所要做的,这个答案也可以帮助你。

有几种方法可以解决这个问题:

  1. 我在我的应用程序中有类似的流程,我解决它的方式是使用从主活动触发的AlertDialog替换登录片段。 所以在你的情况下,片段A出现在屏幕上,如果主要活动认为它需要显示登录对话框,它会显示AlertDialog。 这对我有用。

  2. 当启用片段A时,它可以通过询问FragmentManager来检查片段C是否在周围。 如果存在则删除它。

第1步:当你在片段A中并想要打开片段B时

getFragmentManager().beginTransaction()
.replace(android.R.id.content, new FragmentB(), FragmentB.class.getName()
.addToBackStack(null)
.commit();

第2步:当你在Fragment B中时,想要打开片段C

getFragmentManager().beginTransaction()
.replace(android.R.id.content, new FragmentC(), FragmentC.class.getName()
.disallowAddToBackStack() // << this to make Fragment B, not included in the backstack
.commit();

第3步:当你在Fragment C中,并按下设备后退按钮或getFragmentManager().popBackStack(); 你将打开片段A.

PS:在Activity中使用此getSupportFragmentManager() 如果你在Fragment中使用这个getFragmentManager()

嗨,我只想分享我发现的优雅解决方案。

public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) {
final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1;

fragmentManager.beginTransaction()
    .replace(R.id.content, fragment, tag)
    .addToBackStack(tag)
    .commit();

fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  @Override
  public void onBackStackChanged() {
    int nowCount = fragmentManager.getBackStackEntryCount();
    if (newBackStackLength != nowCount) {
      // we don't really care if going back or forward. we already performed the logic here.
      fragmentManager.removeOnBackStackChangedListener(this);

      if ( newBackStackLength > nowCount ) { // user pressed back
        fragmentManager.popBackStackImmediate();
      }
    }
  }
});
}

来源与解释逻辑

没有告诉FM你想要从B到C的转换被添加到backStack意味着当你回击时,FM没有添加C的记录,所以它不会删除它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM