What is the main difference between calling these methods:
fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, t
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
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
Although it is an old question already answered, maybe those next examples can complement the accepted answer and they can be useful for some new programmers in Android as I am.
Option 1 - "addToBackStack()" is never used
Case 1A - adding, removing, and clicking Back button
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
Case 1B - adding, replacing, and clicking Back button
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
Option 2 - "addToBackStack()" is always used
Case 2A - adding, removing, and clicking Back button
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
Case 2B - adding, replacing, removing, and clicking Back button
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
Option 3 - "addToBackStack()" is not used always (in the below examples, w/o indicates that it is not used)
Case 3A - adding, removing, and clicking Back button
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
Case 3B - adding, replacing, removing, and clicking Back button
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
When We Add First Fragment --> Second Fragment using add() method
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();
}
});
When we use add() in fragment
E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate
E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume
When we use replace() in fragment
going to first fragment to second fragment in First -->Second using replace() method
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
In case of Replace First Fragment these method is extra called ( onPause,onStop,onDestroyView is extra called )
E/Keshav FirstFragment: onPause
E/Keshav FirstFragment: onStop
E/Keshav FirstFragment: onDestroyView
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.
Basic difference between add()
and replace()
can be described as:
add()
is used for simply adding a fragment to some root element.replace()
behaves similarly but at first it removes previous fragments and then adds next fragment.We can see the exact difference when we use addToBackStack()
together with add()
or replace()
.
When we press back button after in case of add()
... onCreateView is never called, but in case of replace()
, when we press back button ... oncreateView is called every time.