Difference between add(), replace(), and addToBackStack()
1) fragmentTransaction.addToBackStack(str);
Description - Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.
2) fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
Description - Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.
3) fragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
Description - Add a fragment to the activity state. This fragment may optionally also have its view (if Fragment.onCreateView returns non-null) into a container view of the activity.
What does it mean to replace an already existing fragment, and adding a fragment to the activity state and adding an activity to the back stack ?
There is a stack in which all the activities in the running state are kept. Fragments belong to the activity. So you can add them to embed them in a activity.
You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. This is essentially useful when you have defined your fragment container at different layouts. You just need to replace with any other fragment in any layout.
When you navigate to the current layout, you have the id of that container to replace it with the fragment you want.
You can also go back to the previous fragment in the backStack with the popBackStack()
method. For that you need to add that fragment in the stack using addToBackStack()
and then commit()
to reflect. This is in reverse order with the current on top.
findFragmentByTag does this search for tag added by the add/replace method or the addToBackStack method ?
If depends upon how you added the tag. It then just finds a fragment by its tag that you defined before either when inflated from XML or as supplied when added in a transaction.
References: FragmentTransaction
One more important difference between add
and replace
is this:
replace
removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView
being invoked. Whereas add
retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in 'paused' state hence when a back button is pressed onCreateView
is not called for the existing fragment(the fragment which was there before new fragment was added).
In terms of fragment's life cycle events onPause
, onResume
, onCreateView
and other life cycle events will be invoked in case of replace
but they wont be invoked in case of add
.
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.
Here is a picture that shows the difference between add()
and replace()
So add()
method keeps on adding fragments on top of the previous fragment in FragmentContainer.
While replace()
methods clears all the previous Fragment from Containers and then add it in FragmentContainer.
What is addToBackStack
addtoBackStack
method can be used with add() and replace methods. It serves a different purpose in Fragment API.
What is the purpose?
Fragment API unlike Activity API does not come with Back Button navigation by default. If you want to go back to the previous Fragment then the we use addToBackStack() method in Fragment. Let's understand both
Case 1:
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragmentContainer, fragment, "TAG")
.addToBackStack("TAG")
.commit();
Case 2:
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragmentContainer, fragment, "TAG")
.commit();
Example an activity have 2 fragments and we use FragmentManager
to replace/add with addToBackstack
each fragment to a layout in activity
Use replace
Go Fragment1
Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume
Go 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
Use add
Go Fragment1
Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume
Go 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
Sample project