add(),replace()和addToBackStack()之间的区别

And*_*Dev 277 android android-fragments

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

fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, tag);
fragmentTransaction.add(containerViewId, fragment, tag);
Run Code Online (Sandbox Code Playgroud)

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

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

Jee*_*van 313

add和之间的另一个重要区别replace是: replace删除现有片段并添加新片段.这意味着当您按下后退按钮时,将创建被替换的片段,并调用其onCreateView.而add保留现有片段并添加一个新片段,这意味着现有片段将处于活动状态,并且它们不会处于"暂停"状态,因此当按下后退按钮onCreateView时不会调用现有片段(在新片段之前存在的片段)加入).就片段的生命周期事件onPause而言,onResume,onCreateView和其他生命周期事件将被调用,replace但是在它们的情况下它们不会被调用add.

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

  • 来自我的+1.知道用新片段替换当前片段非常重要,这意味着当从片段堆栈弹出时,将重新创建先前片段以将其恢复. (4认同)

My *_*God 312

1) fragmentTransaction.addToBackStack(str);

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

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

说明 - 替换添加到容器的现有片段.这与使用相同的containerViewId添加的所有当前添加的片段调用remove(Fragment),然后使用此处给出的相同参数添加(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

  • 因此,我可以在开始的活动开始时通过替换方法添加片段吗? (2认同)
  • 片段容器可以包含多个片段吗,如果是,则replace()方法的行为如何。它将替换该容器中的所有碎片或android api具有接受三个参数的方法,即frgamentContainer,新片段和替换对象。 (2认同)

Roh*_*ngh 77

这是一张图片,显示了add()replace()

在此处输入图片说明

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

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

什么是 addToBackStack

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

什么目的?

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

情况1:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .addToBackStack("TAG")
            .commit();
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

案例2:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .commit();
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 图片胜于雄辩。 (17认同)
  • 如果在情况 1 和 2 中我们使用“替换”代替“添加”会发生什么? (2认同)

Pha*_*inh 76

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

使用替换

去片段1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume
Run Code Online (Sandbox Code Playgroud)

去Fragment2

Fragment2: onAttach
Fragment2: onCreate
Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume
Run Code Online (Sandbox Code Playgroud)

Pop Fragment2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach
Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume
Run Code Online (Sandbox Code Playgroud)

Pop Fragment1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Run Code Online (Sandbox Code Playgroud)

使用添加

去片段1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume
Run Code Online (Sandbox Code Playgroud)

去Fragment2

Fragment2: onAttach
Fragment2: onCreate
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume
Run Code Online (Sandbox Code Playgroud)

Pop Fragment2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach
Run Code Online (Sandbox Code Playgroud)

Pop Fragment1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Run Code Online (Sandbox Code Playgroud)

示例项目


Jav*_*avi 28

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

情况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
Run Code Online (Sandbox Code Playgroud)

选项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
Run Code Online (Sandbox Code Playgroud)

情况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
Run Code Online (Sandbox Code Playgroud)

选项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
Run Code Online (Sandbox Code Playgroud)

情况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
Run Code Online (Sandbox Code Playgroud)


Ava*_*bey 21

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

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

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

当我们在add()... 之后按下后退按钮时,onCreateView永远不会被调用,但是replace()当我们按下后退按钮时......每次调用oncreateView.

  • 那么 add() 是否会导致 android 内存方面的更多负担,因为前一个片段的视图没有被破坏? (2认同)

小智 7

需要注意的重要事项:

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