342

调用这些方法的主要区别是什么:

fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, tag);
fragmentTransaction.add(containerViewId, fragment, tag);

替换已经存在的fragment,将fragment添加到activity状态,将activity添加到back stack是什么意思?

其次,with findFragmentByTag(),这个是搜索add()/replace()方法还是addToBackStack()方法添加的标签?

4

9 回答 9

369

add和之间的另一个重要区别replace是:

replace删除现有片段并添加新片段。这意味着当您按下返回按钮时,被替换的片段将在onCreateView被调用时创建。而add保留现有片段并添加一个新片段,这意味着现有片段将处于活动状态并且它们不会处于“暂停”状态,因此当按下后退按钮时onCreateView不会为现有片段调用(在新片段之前存在的片段是添加)。

就fragment的生命周期事件而言 onPauseonResumeonCreateView其他生命周期事件会被调用,replace但不会被调用add

编辑:如果她使用某种事件总线库(如Greenrobot 的 Eventbus)并重用相同的片段将片段堆叠在其他 via 之上, 则应该小心add。在这种情况下,即使您遵循最佳实践并在onResume其中注册和注销onPause事件总线,事件总线在添加的片段的每个实例中仍然处于活动状态,因为add片段不会调用这些片段生命周期方法中的任何一个。结果,片段的每个活动实例中的事件总线侦听器将处理可能不是您想要的相同事件。

于 2014-02-10T17:56:21.150 回答
363

1) fragmentTransaction.addToBackStack(str);

描述- 将此事务添加到后台堆栈。这意味着事务将在提交后被记住,并在以后从堆栈中弹出时将其操作反转。

2) fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)

描述- 替换已添加到容器中的现有片段。这本质上与为所有当前添加的片段调用 remove(Fragment) 相同,这些片段使用相同的 containerViewId 添加,然后使用此处给出的相同参数调用 add(int, Fragment, String)。

3) fragmentTransaction.add(int containerViewId, Fragment fragment, String tag)

描述- 将片段添加到活动状态。该片段还可以选择将其视图(如果 Fragment.onCreateView 返回非 null)放入活动的容器视图中。

替换已经存在的片段,将片段添加到活动状态并将活动添加到后台堆栈是什么意思?

有一个堆栈,所有处于运行状态的活动都保存在其中。片段属于活动。因此,您可以添加它们以将它们嵌入到活动中。

您可以在单个活动中组合多个片段以构建多窗格 UI 并在多个活动中重用一个片段。当您在不同的布局中定义了片段容器时,这非常有用。您只需要在任何布局中替换为任何其他片段。

当您导航到当前布局时,您可以使用该容器的 id 将其替换为您想要的片段。

popBackStack()您也可以使用该方法返回到 backStack 中的上一个片段。为此,您需要使用然后在堆栈中添加该片段addToBackStack()然后commit()进行反射。这与当前在顶部的顺序相反。

findFragmentByTag 是否搜索由 add/replace 方法或 addToBackStack 方法添加的标签?

是否取决于您添加标签的方式。然后它只是通过它的标记找到一个片段,该标记是您在从 XML 膨胀时或在事务中添加时提供的之前定义的。

参考:FragmentTransaction

于 2013-09-05T10:51:50.850 回答
137

示例一个活动有 2 个片段,我们用每个片段FragmentManager替换/添加addToBackstack到活动中的布局

使用替换

去片段1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume

去片段2

Fragment2: onAttach
Fragment2: onCreate
Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume

流行片段2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach
Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

流行片段1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach

使用添加

去片段1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume

去片段2

Fragment2: onAttach
Fragment2: onCreate
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume

流行片段2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach

流行片段1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach

示例项目

于 2018-01-05T03:48:25.240 回答
105

这是一张显示和之间的区别的add()图片replace()

在此处输入图像描述

所以add()方法继续在 FragmentContainer中的前一个片段之上添加片段。

Whilereplace()方法从 Containers 中清除所有以前的 Fragment,然后将其添加到 FragmentContainer 中。

什么是 addToBackStack

addtoBackStack方法可以与 add() 和 replace 方法一起使用。它在 Fragment API 中有不同的用途。

什么目的?

Fragment API 与 Activity API 不同,默认情况下不带有Back Button 导航。如果你想回到之前的 Fragment,那么我们在 Fragment 中使用 addToBackStack() 方法。让我们了解两者

情况1:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .addToBackStack("TAG")
            .commit();

在此处输入图像描述

案例二:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .commit();

在此处输入图像描述

于 2020-06-13T01:25:48.787 回答
52

尽管这是一个已经回答的老问题,但也许接下来的示例可以补充已接受的答案,并且它们对于像我这样的 Android 中的一些新程序员很有用。

选项 1 - 从不使用“addToBackStack()”

案例 1A - 添加、删除和单击返回按钮

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               App is closed, nothing is visible

案例 1B - 添加、替换和单击返回按钮

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               App is closed, nothing is visible

选项 2 - 始终使用“addToBackStack()”

案例 2A - 添加、删除和单击返回按钮

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Fragment B is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

案例 2B - 添加、替换、删除和单击返回按钮

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView()  
Fragment A :        onPause() - onStop() - onDestroyView() 
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Activity is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onCreateView() - onActivityCreated() - onStart() - onResume()   
Fragment B :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

选项 3 - 并不总是使用“addToBackStack()”(在以下示例中,w/o 表示未使用)

案例 3A - 添加、删除和单击返回按钮

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

案例 3B - 添加、替换、删除和单击返回按钮

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()   
Fragment A :        onPause() - onStop() - onDestroyView() 
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Activity is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible
于 2019-03-27T19:14:06.537 回答
32

add()和之间的基本区别replace()可以描述为:

  • add()用于简单地将片段添加到某个根元素。
  • replace()行为类似,但首先它删除以前的片段,然后添加下一个片段。

当我们与oraddToBackStack()一起使用时,我们可以看到确切的区别。add()replace()

当我们在add()...的情况下按下后退按钮时,永远不会调用 onCreateView,但如果是replace(),当我们按下后退按钮时,每次都会调用 oncreateView。

于 2017-03-02T11:48:42.990 回答
2

当我们添加第一个片段时 --> 使用 add() 方法添加第二个片段

 btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"Click First 
Fragment",Toast.LENGTH_LONG).show();

                Fragment fragment = new SecondFragment();
                getActivity().getSupportFragmentManager().beginTransaction()
                        .add(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
//                        .replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();

            }
        });

当我们在片段中使用 add()

E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate
E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume

当我们在片段中使用 replace()

使用 replace() 方法将 First->Second 中的第一个片段转到第二个片段

 btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"Click First Fragment",Toast.LENGTH_LONG).show();

                Fragment fragment = new SecondFragment();
                getActivity().getSupportFragmentManager().beginTransaction()
//                        .add(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
                        .replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();

            }
        });

E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate

E/Keshav FirstFragment: onPause -------------------------- FirstFragment
E/Keshav FirstFragment: onStop --------------------------- FirstFragment
E/Keshav FirstFragment: onDestroyView -------------------- FirstFragment

E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume

在 Replace First Fragment 的情况下,这些方法是额外调用的( onPause,onStop,onDestroyView 是额外调用的)

E/Keshav FirstFragment: onPause

E/Keshav FirstFragment: onStop

E/Keshav FirstFragment: onDestroyView

于 2019-06-24T10:01:22.777 回答
2

需要注意的重要事项:

Replace 和 Replace with backstack 之间的区别在于,每当我们仅使用 replace 时,片段就会被销毁(调用 ondestroy()),而当我们使用带有 backstack 的 replace 时,不会调用片段 onDestroy()(即按下后退按钮时调用片段及其 onCreateView())

于 2020-03-21T06:28:54.687 回答
0

FragmentManger 的 add 和 replace 函数可以描述为 1. add 表示它将在 Fragment Back Stack 中添加 Fragment,它会在您提供的给定帧处显示,如

getFragmentManager.beginTransaction.add(R.id.contentframe,Fragment1.newInstance(),null)

2.replace 表示您在给定帧用另一个片段替换片段

getFragmentManager.beginTransaction.replace(R.id.contentframe,Fragment1.newInstance(),null)

两者之间的主要实用程序是,当您返回堆叠时,替换将刷新片段,但添加不会刷新前一个片段。

于 2019-09-05T07:36:20.703 回答