I am building a one activity-multiple fragments application. I add to the backstack after every transaction. After a couple of hiding and showing fragments and then I rotate the phone, all the fragments added on the container were restored and every fragment is on top of the other.
What can be the problem? Why is my activity showing the fragments I have previously hidden?
I am thinking of hiding all the previously-hidden-now-shown fragments but is there a more 'graceful' way of doing this?
Use replace() to replace an existing fragment in a container with an instance of a new fragment class that you provide. Calling replace() is equivalent to calling remove() with a fragment in a container and adding a new fragment to that same container. transaction. commit();
The simple answer to that would be call getData from onCreate() , but then I get nullPointer, because at that point I have no AsyncTask . So I need to somehow to know whether fragment was just have been created or it was just detached and then attached again.
Solution: Save required information as an instance variable in calling activity. Then pass that instance variable into your fragment. So following on with my example: before I display F2 I save user data in the instance variable using a callback. Then I start F2, user fills in phone number and presses save.
Use setRetainInstance(true)
on each fragment and your problem will disappear.
Warning: setting this to true will change the Fragments life-cycle.
While setRetainInstance(true)
resolves the issue, there may be cases where you don't want to use it.
To fix that, setup a boolean attribute on the Fragment and restore the visibility:
private boolean mVisible = true;
@Override
public void onCreate(Bundle _savedInstanceState) {
super.onCreate(_savedInstanceState);
if (_savedInstanceState!=null) {
mVisible = _savedInstanceState.getBoolean("mVisible");
}
if (!mVisible) {
getFragmentManager().beginTransaction().hide(this).commit();
}
// Hey! no setRetainInstance(true) used here.
}
@Override
public void onHiddenChanged(boolean _hidden) {
super.onHiddenChanged(_hidden);
mVisible = !_hidden;
}
@Override
public void onSaveInstanceState(Bundle _outState) {
super.onSaveInstanceState(_outState);
if (_outState!=null) {
_outState.putBoolean("mVisible", mVisible);
}
}
Once the configuration changes (e.g. screen orientation), the instance will be destroyed, but the Bundle will be stored and injected to the new Fragment instance.
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