Fragment onResume() & onPause() is not called on backstack
Solution 1:
The fragments onResume()
or onPause()
will be called only when the Activities onResume()
or onPause()
is called.
They are tightly coupled to the Activity
.
Read the Handling the Fragment Lifecycle section of this article.
Solution 2:
- Since you have used
ft2.replace()
,FragmentTransaction.remove()
method is called and theLoginfragment
will be removed. Refer to this. SoonStop()
ofLoginFragment
will be called instead ofonPause()
. (As the new fragment completely replaces the old one). - But since you have also
used
ft2.addtobackstack()
, the state of theLoginfragment
will be saved as a bundle and when you click back button fromHomeFragment
,onViewStateRestored()
will be called followed byonStart()
ofLoginFragment
. So eventuallyonResume()
won't be called.
Solution 3:
Here's my more robust version of Gor's answer (using fragments.size()is unreliable due to size not being decremented after fragment is popped)
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getFragmentManager() != null) {
Fragment topFrag = NavigationHelper.getCurrentTopFragment(getFragmentManager());
if (topFrag != null) {
if (topFrag instanceof YourFragment) {
//This fragment is being shown.
} else {
//Navigating away from this fragment.
}
}
}
}
});
And the 'getCurrentTopFragment' method:
public static Fragment getCurrentTopFragment(FragmentManager fm) {
int stackCount = fm.getBackStackEntryCount();
if (stackCount > 0) {
FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(stackCount-1);
return fm.findFragmentByTag(backEntry.getName());
} else {
List<Fragment> fragments = fm.getFragments();
if (fragments != null && fragments.size()>0) {
for (Fragment f: fragments) {
if (f != null && !f.isHidden()) {
return f;
}
}
}
}
return null;
}
Solution 4:
If you really want to replace fragment inside other fragment you should use Nested Fragments.
In your code you should replace
final FragmentManager mFragmentmanager = getFragmentManager();
with
final FragmentManager mFragmentmanager = getChildFragmentManager();
Solution 5:
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> fragments = getFragmentManager().getFragments();
if (fragments.size() > 0 && fragments.get(fragments.size() - 1) instanceof YoureFragment){
//todo if fragment visible
} else {
//todo if fragment invisible
}
}
});
but be careful if more than one fragment visible