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

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

替换一个已经存在的片段,并将一个片段添加到活动状态,并将一个活动添加到后台堆栈,这意味着什么?

其次,使用findFragmentByTag(),是否搜索由add()/replace()方法或addToBackStack()方法添加的标记?


1) fragmentTransaction.addToBackStack(str);

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

2) fragmentTransaction。替换(int containerViewId, Fragment片段,String标签)

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

3) fragmentTransaction。add(int containerViewId, Fragment片段,String标签)

描述-为活动状态添加一个片段。这个片段也可以有它的视图(如果片段。onCreateView返回非空)到活动的容器视图中。

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

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

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

当您导航到当前布局时,您有该容器的id,可以将其替换为所需的片段。

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

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

If取决于您如何添加标签。然后,它仅通过您之前定义的标记(在从XML膨胀时或在添加到事务时提供的标记)找到一个片段。

引用:FragmentTransaction


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

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

就片段的生命周期事件而言,onPause, onResume, onCreateView和其他生命周期事件将在替换的情况下被调用,但在添加的情况下不会被调用。

Edit: One should be careful if she is using some kind of event bus library like Greenrobot's Eventbus and reusing the same fragment to stack the fragment on top of other via add. In this scenario, even though you follow the best practice and register the event bus in onResume and unregister in onPause, event bus would still be active in each instance of the added fragment as add fragment wont call either of these fragment life cycle methods. As a result event bus listener in each active instance of the fragment would process the same event which may not be what you want.


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

Add()用于简单地向某个根元素添加片段。 Replace()的行为类似,但首先它删除之前的片段,然后添加下一个片段。

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

当我们按下返回按钮后,如果add()…onCreateView从未被调用,但在replace()的情况下,当我们按下返回按钮…每次都调用oncreateView。


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

使用替换

去Fragment1

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

去Fragment2

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

流行Fragment2

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

流行Fragment1

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

使用添加

去Fragment1

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

去Fragment2

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

流行Fragment2

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

流行Fragment1

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

示例项目


虽然这是一个已经回答过的老问题,但也许下面的例子可以补充这个公认的答案,它们可以对像我这样的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

使用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();

            }
        });

当我们在fragment中使用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

当在fragment中使用replace()时

使用replace()方法将第一个片段转换到first中的第二个片段

 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是额外调用的)

S / o

我/你

我/你


FragmentManger的添加和替换功能可以这样描述 1. 添加意味着它会将片段添加到片段返回堆栈中,并在您提供的给定帧中显示 就像

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

2.替换意味着你在给定的帧中用另一个片段替换这个片段

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

两者之间的主要实用程序是,当你回堆叠时,replace将刷新片段,而add将不会刷新之前的片段。


需要注意的重要事项:

Replace和backstack Replace之间的区别是,当我们只使用Replace时,片段就会被销毁(ondestroy()被调用),而当我们使用backstack时,片段ondestroy()不会被调用(即当返回按钮被按下时,片段会被其onCreateView()调用)


下面的图片显示了add()和replace()之间的区别

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

replace()方法清除容器中所有之前的Fragment,然后将其添加到FragmentContainer中。

什么是addToBackStack

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

目的是什么?

片段API与活动API不同,默认情况下没有返回按钮导航。如果你想回到之前的Fragment,那么我们在Fragment中使用addToBackStack()方法。我们来理解一下

案例1:

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

案例2:

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