I have multiple fragment inside an activity. On a button click I am starting a new fragment, adding it to backstack. I naturally expected the onPause()
method of current Fragment and onResume()
of new Fragment to be called. Well it is not happening.
LoginFragment.java
public class LoginFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
final FragmentManager mFragmentmanager = getFragmentManager();
Button btnHome = (Button)view.findViewById(R.id.home_btn);
btnHome.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
HomeFragment fragment = new HomeFragment();
FragmentTransaction ft2 = mFragmentmanager.beginTransaction();
ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
, R.anim.slide_left, R.anim.slide_out_right);
ft2.replace(R.id.middle_fragment, fragment);
ft2.addToBackStack("");
ft2.commit();
}
});
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of LoginFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of loginFragment");
super.onPause();
}
}
HomeFragment.java
public class HomeFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of HomeFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of HomeFragment");
super.onPause();
}
}
What I expected, was,
- When button is clicked, LoginFragment gets replaced with
HomeFragment,
onPause()
of LoginFragment, andonResume()
of HomeFragment gets called - When back is pressed, HomeFragment is poped out and LoginFragment is
seen, and
onPause()
of HomeFragment andonResume()
of LoginFragment gets called.
What I am getting is,
- When button is clicked, HomeFragment is correctly replacing LoginFragment, onResume() of HomeFragment is called, but onPause() of LoginFragment is never called.
- When back pressed, HomeFragment is correctly popping to reveal LoginFragment, onPause() of HomeFragment gets called, but onResume() of LoginFragment never gets called.
Is this the normal behaviour? Why is onResume()
of LoginFragment not getting called when I press the back button.
Calling
ft.replace
should trigger the onPause (of the replaced fragment) and onResume (of the replacing fragment).I do notice that your code inflates
login_fragment
on the home fragment, and also doesn't return the views in the onCreateView. If these are typos, can you show how these fragments are being called from within your activity?While creating a fragment transaction, make sure to add the following code.
Also make sure, to commit the transaction after adding it to backstack
but be careful if more than one fragment visible
Based on the answer of @Gor I wrote similar in Kotlin. Place this code in
onCreate()
of an activity. It works for one fragment visible. If you haveViewPager
with fragments, it will callViewPager
's fragment, not a previous one.After reading https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 I understood that it would be better in many situations to attach new fragments with
replace
, notadd
. So a need inonResume
in some cases will disappear.Although with different code, I experienced the same problem as the OP, because I originally used
instead of
With "replace" the first fragment gets recreated when you return from the second fragment and therefore onResume() is also called.
Follow the below steps, and you shall get the needed answer
1- For both fragments, create a new abstract parent one.
2- Add a custom abstract method that should be implemented by both of them.
3- Call it from the current instance before replacing with the second one.