当前位置: 首页 > 知识库问答 >
问题:

防止同一片段多次堆叠(addToBackStack)

向俊贤
2023-03-14

我有一个带有三个Fragments的活动,让我们称它们为A、B和C。片段A在活动onCreate()中调用。

FragmentA fragA = new FragmentA();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.activity2_layout, fragA, "A");
transaction.commit();

并在按下某些按钮时被替换为片段B或C,并且FragmentTransaction调用addToBackStack()

FragmentB fragB = new FragmentB(); //or C
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.activity2_layout, fragB, "B");  //or C
transaction.addToBackStack("B"); //or C
transaction.commit();

但是,假设我连续三次调用片段B,我如何防止它自己堆积到它身上呢?同时我希望这是可能的:B呼叫

共有2个答案

方琦
2023-03-14

我已经解决了您的一个问题,即如何防止它自己堆叠在它身上?,不久前在我自己的一个项目中。这是我在那里使用的确切代码:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) {
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content);
    if (current == null || !current.getClass().equals(fragment.getClass())) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null).add(R.id.main_content, fragment).commit();
        } else {
            transaction.replace(R.id.main_content, fragment).commit();
        }
    }
}

这段代码所做的是检查当前显示的片段是什么类,并将其与您要替换它的片段进行比较。如果它们相同,它什么也不做。此代码可以按照您的需要进行调整

Fragment newFragment = new FragmentB(); //OR FragmentC
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout);
if (!current.getClass().equals(newFragment.getClass())) {

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    final String tag = newFragment.getClass().getSimpleName();
    transaction.addToBackStack(tag);
    transaction.add(R.id.activity2_layout, newFragment, tag);
    transaction.commit();
} else {
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME
}

确保一次只存在一个特定类型的碎片可能是通过在同一碎片第一次出现之前弹出后退来实现的。我没有为此编写任何代码,但实现该功能应该不会太困难。如果你自己无法理解,请告诉我,我会尝试给你写一个例子:)

郭曾笑
2023-03-14

从如何从BackStack恢复片段(如果存在),这可能与您的查询非常相似。

有一种方法可以根据commit提供的事务名称或id弹出后栈(例如,使用Thijs已经提到的片段类名):

String backStateName = fragment.getClass().getName();

添加到Backback:

FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();

弹出时:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

所以在替换片段之前,我们可以检查后台是否存在,比如:

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

if (!fragmentPopped){ //fragment not in back stack, create it.
    ...
    ...
    ft.addToBackStack(backStateName);
    ft.commit();
}

请检查以上问题和已接受的答案以获取更多解释。

 类似资料:
  • 嗨,伙计们,这是我的密码 我基本上只有2个碎片,只有家庭装饰应该添加到背面堆叠。在HomeFragment和OtherFragment之间切换了一段时间,然后在HomeFragment上单击back按钮,最后我会看到HomeFragment显示了好几次。在家庭框架内有一个回收视图。当我上下滚动时,我真的可以看到行显示了多次。我如何才能确保家庭装饰只添加到一次后堆栈。 谢谢

  • 我有一个对象Foo,它可以使用片段(efFraank)进行配置。Foo类包含对FooFraank的静态引用和方法public Fraank getConfigurationFraank();此方法将当前对象分配给FooFraank并返回它。 足球碎片大致如下: 当我第一次在对象foo1上使用片段时,一切都很好。显示正确的信息,一切正常。 当我在另一个对象foo2上第二次使用该片段时,打开该片段会导

  • 问题内容: 当用户单击登录或注册按钮时,我试图阻止多个请求。这是我的代码,但是不起作用。只是第一次工作正常,然后返回false。 有任何想法吗?谢谢! 问题答案: 问题在这里: 不再指向按钮。

  • 问题内容: 我有几个使用相同的JNI库的类,称为“ jni”。在每个此类中,我在该类的静态初始值设定项中都有一个System.loadLibrary()调用: 唯一的问题是,我只希望System.loadLibrary()被调用一次,因为这可能需要一段时间。有没有一种简便的方法来防止同一库的多次加载? 问题答案: 如果已经加载了库,则随后的任何加载相同库的调用都将被忽略。 : 加载由libname

  • 不知道你是否曾经看到过一个论坛或者博客,在一个帖子或者文章后面出现多条重复的记录,这些大多数是因为用户重复递交了留言的表单引起的。由于种种原因,用户经常会重复递交表单。通常这只是鼠标的误操作,如双击了递交按钮,也可能是为了编辑或者再次核对填写过的信息,点击了浏览器的后退按钮,然后又再次点击了递交按钮而不是浏览器的前进按钮。当然,也可能是故意的——比如,在某项在线调查或者博彩活动中重复投票。那我们如

  • 问题内容: 在我的React组件中,我有一个按钮,当单击该按钮时,它会通过AJAX发送一些数据。我只需要第一次发生,即在首次使用后禁用该按钮。 我如何尝试做到这一点: 我认为发生的事情是状态变量没有立即更新,这是React文档所说的预期。 我如何强制按钮被禁用或在单击按钮时立即消失? 问题答案: 您可以做的是单击该按钮后将其禁用,然后将其保留在页面中(不可单击的元素)。 为此,您必须向按钮元素添加