Understanding Fragment's lifeCycle methods calls during fragment transaction
Asked Answered
C

3

31

I created a demo to understand which all fragment lifecycle's methods are called during different cases of fragment transaction.While most of the calls are as per expectation few things I am still confused which I have written in Bold.

Suppose two fragment A and B are there and we are performing transaction between them

Case 1

When Fragment B is added to Fragment A

getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, fragementB).addToBackStack(null).commit();

Fragment B

onAttach

onCreate

onCreateView

onActivityCreated

onStart

onResume

No lifecycle methods of Fragment A is being called.

What i expected was?

onStop method of Fragment A is called since Fragment A is not visible

As per documentation-

Stopped- The fragment is not visible. Either the host activity has been stopped or the fragment has been removed from the activity but added to the back stack. A stopped fragment is still alive (all state and member information is retained by the system). However, it is no longer visible to the user and will be killed if the activity is killed.

Does this mean that no method of current fragment is called when new fragment is added in same activity?

Then using popBackStack() in Fragment B

Fragment B

onPause

onStop

onDestroyView

onDestroy

onDetach

No lifecycle methods of Fragment A is being called

What i expected was?

onStart method of Fragment A is called since Fragment A is visible now

Case 2

When Fragment B replaces Fragment A

getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragementB).commit();

Fragment B

onAttach

onCreate

onCreateView

onActivityCreated

onStart

onResume

Fragment A

onPause

onStop

onDestroyView

onDestroy

onDetach

Everything was as per expectation

Case 3

When Fragment B replaces Fragment A keeping it in backstack

 getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragementB).addToBackStack("tag").commit();

Fragment B

onAttach

onCreate

onCreateView

onActivityCreated

onStart

onResume

Fragment A

onPause

onStop

onDestroyView

onDestroy and onDetach method of Fragment A is NOT called.Why its not called?Bcoz as per documentation method replace removes any fragments that are already in the container and add your new one to the same container

Then using popBackStack() in Fragment B

Fragment A

onCreateView

onActivityCreated

onStart

onResume

Fragment B

onPause

onStop

onDestroyView

onDestroy

onDetach

Chellean answered 14/2, 2017 at 5:28 Comment(1)
Thanks to Hanan Rofe Haim..I have posted in detail with explanation on blog..It explains fragment lifecycle during fragment transaction with latest appcompat version..Check out - androidlearnersite.wordpress.com/2017/02/27/…Chellean
A
30

Does this mean that no method of current fragment is called when new fragment is added in same activity?

Correct, your first fragment A will only be affected if it's removed or replaced (case 2). Simply adding another fragment will just display fragment B over fragment A and no life cycle callbacks should be called.

What i expected was?

onStart method of Fragment A is called since Fragment A is visible now

Again, since fragment B was added on top of A, fragment A is not affected by the removal of B.

onDestroy and onDetach method of Fragment A is NOT called.Why its not called?Bcoz as per documentation method replace removes any fragments that are already in the container and add your new one to the same container

Unlike a simple replace, when you add your replace transaction to the backstack you're actually keeping the first fragment attached to it's activity, only its view is destroyed.

Once you pop the backstack fragment B is removed and fragment A will just recreate its view - starting from onCreateView().

Airworthy answered 14/2, 2017 at 22:55 Comment(1)
Plain and clean answer.Nubilous
D
7

I run some logs to see the results are as follows (just like done in activities here: https://mcmap.net/q/80309/-android-activity-life-cycle-what-are-all-these-methods-for

Fragment Start

On Fragment Launched (First Time)
———————————————————————
onAttach: 
onCreateView:
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


On Coming Back To Fragment (From another fragment)
———————————————————————
onCreateView: 
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


OnMaximize(Square Button-After Back Pressed)
———————————————————————
onAttach: 
onCreateView: 
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


OnMaximize(Square Button-After Circle Button)
———————————————————————
onStart: 
onResume:


OnMaximize(After Circle Button)
————————————————————————————————————————————————
onStart: 
onResume:

Fragment Stopped

On Going To Another Fragment (Skipping 1 Fragment)
———————————————————————
onPause: 
onStop: 
onDestroyView: 


On BackPressed - Reverse Triangle Button (App Minimized)
———————————————————————
onPause: 
onStop: 
onDestroyView: 
onDestroy: 
onDetach: 


OnMinimize (Circle Button)
————————————————————————————————————————————————
onPause: 
onStop: 


OnMinimize (Square Button)
————————————————————————————————————————————————
onPause: 
onStop: 


Going To Another Activity
————————————————————————————————————————————————
onPause: 
onStop: 


Close The App
————————————————————————————————————————————————
onDestroyView: 
onDestroy:

If someone wants to recreate to check following is the code:

public View onCreateView(@NonNull LayoutInflater inflater,
                         @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {

    Log.d("TAG",
          "onCreateView: ");
}

@Override
public void onAttach(Context context) {
    Log.d("TAG",
          "onAttach: ");
    super.onAttach(context);
}

@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) {

    Log.d("TAG",
          "onViewCreated: ");
    super.onViewCreated(view,
                        savedInstanceState);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    Log.d("TAG",
          "onActivityCreated: ");
    super.onActivityCreated(savedInstanceState);
}

@Override
public void onStart() {
    Log.d("TAG",
          "onStart: ");
    super.onStart();
}

@Override
public void onResume() {

    Log.d("TAG",
          "onResume: ");

    reAttachListeners();
    super.onResume();
}

@Override
public void onPause() {
    super.onPause();

    Log.d("TAG",
          "onPause: ");
    removeListeners();

}

@Override
public void onStop() {
    Log.d("TAG",
          "onStop: ");
    super.onStop();
}

@Override
public void onDestroyView() {
    Log.d("TAG",
          "onDestroyView: ");
    super.onDestroyView();
}

@Override
public void onDestroy() {
    Log.d("TAG",
          "onDestroy: ");
    super.onDestroy();
}

@Override
public void onDetach() {

    Log.d("TAG",
          "onDetach: ");
    super.onDetach();
}
Daddy answered 21/4, 2020 at 6:43 Comment(1)
Just like in the activity onPause and onResume seem to be called all the time except for closing the app... so this helps with firebase listeners, I am surprised there are so many tutorials which do not cover this critical aspect of attaching and detaching addvalueeventlisteners...Daddy
T
-6

setUserVisibleHint will be called when fragment visible or not visible

Tropopause answered 14/2, 2017 at 5:37 Comment(1)
It is basically a setter which sets a hint to the system about whether this fragment's UI is currently visible to the user.It is not a lifecycle method which will be called when new fragment is added or replaced to current fragmentChellean

© 2022 - 2024 — McMap. All rights reserved.