调用这些方法之间的主要区别是:

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


替换一个已经存在的片段,并向活动状态添加一个片段,并添加一个其次,对于findFragmentByTag(),这是否搜索通过add() / replace()方法或addToBackStack()方法添加的标签?

#1 楼

1)fragmentTransaction.addToBackStack(str);

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

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

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

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

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


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


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

您可以将多个片段组合在一个活动中,以构建多窗格UI,并在多个活动中重复使用一个片段。当您在不同的布局中定义了片段容器时,这实际上很有用。您只需要用任何布局中的任何其他片段替换即可。

导航到当前布局时,您具有该容器的ID,可以用所需的片段替换它。

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


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


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

参考文献:FragmentTransaction

评论


因此,我可以在开始的活动开始时通过替换方法添加片段吗?

– Yohanes AI
2014年9月13日下午5:49

(之前未添加任何片段)

– Yohanes AI
2014年9月13日下午5:56

片段容器可以包含多个片段吗,如果是,则replace()方法的行为如何。它将替换该容器中的所有碎片或android api有一个接受三个参数的方法,即frgamentContainer,新片段以及替换对象。

– ved
15年6月21日在18:20

@ved否,它将用当前的片段替换容器中当前存在的所有片段。

–reubenjohn
2015年7月1日14:35



#2 楼

addreplace之间的另一个重要区别是:

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

就片段的生命周期事件而言,onPauseonResumeonCreateView和其他生命周期事件在replace时将被调用,但在add情况下将不会被调用。

编辑:如果她正在使用诸如Greenrobot的Eventbus之类的事件总线库,并通过add重用相同的片段将片段堆叠在另一个片段上,则应格外小心。在这种情况下,即使您遵循最佳做法,并在onResume中注册了事件总线,并在onPause中取消了注册,事件总线在添加的片段的每个实例中仍然处于活动状态,因为add片段不会调用这两个片段生命周期方法中的任何一个。结果,片段的每个活动实例中的事件总线侦听器将处理可能不是您想要的事件。

评论


我认为一种方法可能是在最上面的片段中处理事件,并在处理完成后调用cancelEventDelivery()。您可以在github.com/greenrobot/EventBus/blob/master/…中找到有关cancelEventDelivery()方法的更多信息。

–Jeevan
2015年4月9日在8:36

向我+1。知道用新片段替换当前片段非常重要,这意味着从片段堆栈弹出时将重新创建以前的片段以将其取回。

– AndaluZ
16-3-21在12:53

onPause,onResume与主机活动紧密相关。当替换片段时,他们没有打电话。

– AndroidGeek
16年8月8日在7:14

只是要添加这一点,如果您正在使用EventBus,则可以添加带有Tag的片段,并将该片段从片段传递到事件,然后检查是否将调用所有eventbus,您只需指定应执行的事件总线即可。

–user2582318
2016年9月6日,下午1:52

必须提到的是,您正在与add()或replace()方法一起调用addToBackStack()。

–rahil008
19年2月8日在10:37

#3 楼

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

使用replace

转到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


Pop Fragment2

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


Pop Fragment1

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


使用add

转到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


Pop Fragment2

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


Pop Fragment1

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


样本项目

评论


不是应该在每个Pop动作的onStop()之前调用onPause()吗?

– iCantC
19年10月2日在17:21

区分“ add()”和“ replace()”的绝佳答案,尽管缺少addToBackStack()。投票

–希里(Shirish Herwade)
19-11-28在11:07



@ShirishHerwade我相信他在两种情况下都展示了add和replace用addToBackStack的区别。

–Cyber​​Shark
4月8日晚上11:23

#4 楼

尽管这是一个已经解决的老问题,但是也许下一个示例可以补充已接受的答案,对于像我这样的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


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


评论


足够彻底。好功夫!

– Manish Kumar Sharma
19年7月27日在16:41

那么我们可以说在处理片段时,后退按钮的工作方式与FragmentManager.popBackStack()函数类似吗?

–丁丁
19/09/26'9:36

很好的答案,再好不过了。这应该被接受。

–希里(Shirish Herwade)
19年11月29日在10:09

#5 楼

add()replace()之间的基本区别可以描述为:add()用于将片段简单地添加到某个根元素。

replace()的行为类似地,但首先删除先前的片段,然后添加下一个片段。

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

当我们按回对于add() ...之后的按钮,永远不会调用onCreateView,但是对于replace()而言,当我们按返回按钮时,每次都会调用... oncreateView。

评论


那么由于前一个片段的视图没有被破坏,add()是否会给Android内存带来更多负担?

– Derekyy
17年4月20日在12:28

@Derekyy是的,我认为是。

– Arpit J.
1月14日7:45

这就是我想要的

– parvez rafi
6月9日下午3:38

#6 楼

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



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

尽管replace()方法从容器中清除了所有先前的片段,然后将其添加到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();



情况2:

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




评论


图片胜于雄辩。

– Sachin
7月2日7:00

最好的答案!

–扎卡·罗迪诺夫(Zakhar Rodionov)
11月3日8:39

#7 楼

当我们使用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()方法

 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 / KeshavFirstFragment:onStop

E / KeshavFirstFragment:onDestroyView

#8 楼

FragmentManger的功能add和replace可以描述为这些
1。 add表示它将片段添加到片段堆栈中,并在给定的帧处显示您正在提供的内容。


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

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

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

两者之间的主要实用程序是,当您反向堆叠时,替换将刷新该片段,但添加将不刷新以前的片段。

#9 楼

需要注意的重要事项:

用backstack替换和替换之间的区别是,每当我们仅使用replace时,该片段就会被销毁(调用ondestroy()),而当使用backstack替换时,则片段onDestroy( )不会被调用(即,当按下后退按钮时,会使用其onCreateView()调用fragment