使用null参数的addToBackStack的含义是什么?

117

我有一个客户代码。所有片段都只有一个活动,即单个活动管理所有片段。

此活动包含以下代码,用于该片段的方法结束 -

例如 - 片段MoreFragment:

MoreFragment firstFragment = new MoreFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.article_fragment, firstFragment)
.addToBackStack(null).commit();

所以,

1)addToBackStack(null)跟随commit()的意义是什么?

2)为什么需要传递一个空参数到addToBackStack

3)如何在这样添加后获取该片段?

看起来这段代码是无用的,因为我在没有最后一行.addToBackStack(null).commit()的情况下运行了代码,没有任何问题。


在某些情况下,您必须调用该方法:http://developer.android.com/reference/android/app/FragmentTransaction.html#addToBackStack(java.lang.String)。 - Lucifer
https://dev59.com/RWYq5IYBdhLWcg3weAej#18846336 - Lucifer
3
你可以将片段名称作为参数传递给addToBackStack(name),而不是null。如果你传递了null,则无法使用方法FragmentManager.popBackStackImmediate(String name, int flags);或popBackStack(String name, int flags);,因为名称为null。所以这些popBackstack方法将不起作用。我建议你传递片段名称作为参数,而不是传递null。 - luckylukein
这是交易的名称。不需要名称即可弹出后退堆栈并撤消交易。 - the_prole
3个回答

124
addToBackStack(null)方法跟随commit()的调用是什么意思?引用文档如下:
通过调用addToBackStack(),替换事务将保存到后退堆栈中,以便用户可以通过按“返回”按钮撤消事务并通过带回前一个片段。
如果您向事务添加多个更改(例如另一个add()或remove())并调用addToBackStack(),则在调用commit()之前应用的所有更改都作为单个事务添加到后退堆栈中,并且Back按钮将一起反转它们。
除了以下情况,将更改添加到FragmentTransaction的顺序无关紧要:
必须最后调用commit()。如果您正在将多个片段添加到同一个容器中,则将它们添加的顺序确定它们在视图层次结构中出现的顺序。
所以你必须在最后提交。
为什么需要传递null参数给addToBackStack?
它不需要为null,它可以是一个字符串。如果不想,只需传递null。 public abstract FragmentTransaction addToBackStack(String name)
API级别11中新增 将此事务添加到后退堆栈中。这意味着该事务将在提交后记住其操作,并在稍后从堆栈弹出时反转其操作。
参量名-此后退堆栈状态的可选名称,或null。
似乎这段代码是无用的,因为我没有最后一行.addToBackStack(null).commit()运行代码而没有任何问题
如果要导航到以前的片段,请将其添加到后退堆栈中。因此,这取决于您是否想将片段添加到后退堆栈。
如何在添加了片段之后获取该片段?

您已经拥有了碎片实例firstFragment,所以我不知道您说的“稍后获取片段”的意思。

更多信息请参见:

http://developer.android.com/guide/components/fragments.html

http://developer.android.com/reference/android/app/FragmentTransaction.html#addToBackStack(java.lang.String)


您还可以从API文档中添加此内容到您的答案中:将此事务添加到后退栈。这意味着该事务将在提交后被记住,并在稍后从堆栈中弹出时撤消其操作。参数 name:此后退栈状态的可选名称,或null。 - Dyrborg
据我所理解,将其添加到后退堆栈的整个目的是执行导航,就像我们使用“返回”按钮转到先前的片段一样。 - My God
如果您正在向addToBackStack传递参数,那么为什么我们需要使用getFragmentManager().popBackStackImmediate(),如果返回按钮可以自行完成带/不带参数的操作?请参阅以下答案 - https://dev59.com/jWEi5IYBdhLWcg3wjs9j - My God
@VedPrakash 不需要这样做。而且那是完全不同的问题和答案。你可以很容易地通过将两个片段添加到后退堆栈中并按返回按钮来自己找出答案。 - Raghunandan
1
当使用 String name 时会有什么“有用”的作用呢? - M.kazem Akhgary
显示剩余2条评论

26

addToBackStack(String name)方法中的tag字符串提供了一种定位后退栈以便稍后直接弹出到该位置的方式。它旨在用于popToBackStack(String name, int flags)方法:

从管理器的片段回退栈中弹出上一个片段转换。此函数是异步的--它将请求排队以进行弹出,但在应用程序返回其事件循环之前不会执行操作。

name:如果非空,则这是要查找的先前状态的名称;如果找到,则将弹出所有状态直到该状态。可以使用POP_BACK_STACK_INCLUSIVE标志来控制是否弹出命名状态本身。如果为空,则只会弹出顶部状态。

flags:0或POP_BACK_STACK_INCLUSIVE

换句话说,它将弹出您的后退栈,直到找到由addToBackStack(String name)中的name添加的片段。

例如,如果您对片段管理器进行了一系列添加或替换,并给出了名称“frag1”、“frag2”、“frag3”、“frag4”,并希望稍后直接返回添加了addToBackStack("frag2")的第2个片段,则调用popToBackStack("frag2", 0)

因此,

  • 使用 .addToBackStack("fragName"):如果您希望稍后的 popToBackStack(String name, int flags) 弹出多个后退栈。

  • 使用 .addToBackStack(null):如果您不想稍后弹出多个后退栈,但仍然想逐一弹出一个。即使您不会显式调用 popToBackStack(),而是让后退按键默认实现处理后退栈,也要这样做。

  • 使用 .disallowAddToBackStack():如果您既不想使用后退按键,也不想显式调用 popBackStack()。 它将确保代码中没有部分使用了 .addToBackStack()。


2

您的答案已经过时。如果您不想将片段添加到返回堆栈中,您应该使用以下代码片段:

    public static void replaceFragment (@NonNull FragmentManager fragmentManager,
            @NonNull Fragment fragment, int frameId){

        checkNotNull(fragmentManager);
        checkNotNull(fragment);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(frameId, fragment);
        transaction.disallowAddToBackStack(); // <-- This makes magic!
        transaction.commit();
    }

以下是一个示例,可以很好地展示如何使用它:

您可以看到这个可爱的示例:

GameFragment fragment = GameFragment.newInstance(mGameObject, currentQuestion);
ActivityUtils.replaceFragment(getFragmentManager(), fragment, R.id.main);

6
哪里被弃用了?我在文档或FragmentTransaction源代码中没有看到任何信息。 - Rup
3
注意,如果你使用 disallowAddToBackStack,那么任何对 addToBackStack 的后续调用都会抛出 IllegalStateException 异常。如果已经调用了 addToBackStack 方法,则该方法也会抛出 IllegalStateException 异常。 - Kathir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接