I am maintaining a backstack of fragments and pop the stack when back button is pressed. I need to reload data every time a fragment is made visible and do some cleanup when it gets hidden. For this I need to detect when a fragment is shown and hidden. This is a very common question but surprisingly none of accepted answers work for me. I
I am adding fragments to backstack using code like this:
public void pushFragment(Fragment f) {
getFragmentManager().beginTransaction()
.add(R.id.content_frame, f, null)
.addToBackStack(null)
.commit();
}
I am popping fragments off using this code:
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
I am trying to detect from a fragment class when it becomes visible or hidden (either because it is being popped off the stack or another fragment was pushed on top). So far I have tried these callbacks:
Is there a Fragment callback that will let me detect when a fragment is being shown or hidden? I will rather not use a backstack listener because I want every fragment class to have its own show/hide logic.
Edit:
If I use replace()
to add the fragment (instead of add()
) then the view for the previously shown fragment gets destroyed. As a result if that fragment ever to appear on top of the stack again its view is recreated. In this situation onViewCreated/onDestroyView or onStart/onStop will be called every time a fragment is shown or hidden. I suppose I could use that approach. The down side is that the views are created and destroyed frequently. I might as well be using activities instead of fragments for master-detail navigation in that case.
fragment:fragment:1.1. 0 you can just use onPause and onResume callbacks to determine which fragment is currently visible for the user. onResume callback is called when fragment became visible and onPause when it stops to be visible.
You can use findFragmentByTag() or findFragmentById() functions to get a fragment. If mentioned methods are returning null then that fragment does not exist.
To get the current fragment that's active in your Android Activity class, you need to use the supportFragmentManager object. The supportFragmentManager has findFragmentById() and findFragmentByTag() methods that you can use to get a fragment instance.
onStart()The onStart() method is called once the fragment gets visible. onResume()Fragment becomes active.
Edit again If you need a callback you can override onHiddenChanged like this:
public void onHiddenChanged(boolean hidden) {
if(hidden){// Do you stuff here}
}
As PPartisan mentioned you claimed that onHiddenChanged
is never called.
The reason for that is because onHiddenChanged
doesn't get called the first time an fragment is shown.
Called when the hidden state (as returned by isHidden()) of the fragment has changed. Fragments start out not hidden; this will be called whenever the fragment changes state from that.
To fix this: add this to your code:
FragmentTransaction mFragmentTransaction = getFragmentManager().beginTransaction();
if (f!= null) {
mFragmentTransaction .hide(f);
}
mFragmentTransaction.add(R.id.content_frame, f, null)
mFragmentTransaction.addToBackStack(null)
mFragmentTransaction.commit();
More on the on this SO thread
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With