I am really confused with the internal state of a Fragment. I have an Activity holding only one Fragment at once and replaces it, if another Fragment should get shown. From the docs onSaveInstanceState
is called ONLY if the Activitys onSaveInstanceState
is getting called (which isn't called in my case).
If I stop my Fragment, I'll store its state myself inside a Singleton (yeah, I know I hate Singletons, too, but wasn't my idea to do so). So I have to recreate the whole ViewHirarchy
, create new Views (by using the keyword new
), restore its state and return them in onCreateView
. I also have a Checkbox inside this View from which I explicitly do NOT want to store its state.
However the FragmentManager
wants to be "intelligent" and calls onViewStateRestored
with a Bundle I never created myself, and "restores" the state of the old CheckBox
and applies it to my NEW CheckBox. This throws up so many questions:
Can I control the bundle from onViewStateRestored
?
How does the FragmentManager take the state of a (probably garbage-collected) CheckBox and applies it to the new one?
Why does it only save the state of the Checkbox (Not of TextViews??)
So to sum it up: How does onViewStateRestored
work?
Note I'm using Fragmentv4, so no API > 17 required for onViewStateRestored
Well, sometimes fragments can get a little confusing, but after a while you will get used to them, and learn that they are your friends after all.
If on the onCreate() method of your fragment, you do: setRetainInstance(true); The visible state of your views will be kept, otherwise it won't.
Suppose a fragment called "f" of class F, its lifecycle would go like this: - When instantiating/attaching/showing it, those are the f's methods that are called, in this order:
F.newInstance(); F(); F.onCreate(); F.onCreateView(); F.onViewStateRestored; F.onResume();
At this point, your fragment will be visible on the screen. Assume, that the device is rotated, therefore, the fragment information must be preserved, this is the flow of events triggered by the rotation:
F.onSaveInstanceState(); //save your info, before the fragment is destroyed, HERE YOU CAN CONTROL THE SAVED BUNDLE, CHECK EXAMPLE BELLOW. F.onDestroyView(); //destroy any extra allocations your have made //here starts f's restore process F.onCreateView(); //f's view will be recreated F.onViewStateRestored(); //load your info and restore the state of f's view F.onResume(); //this method is called when your fragment is restoring its focus, sometimes you will need to insert some code here. //store the information using the correct types, according to your variables. @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putSerializable("foo", this.foo); outState.putBoolean("bar", true); } @Override public void onViewStateRestored(Bundle inState) { super.onViewStateRestored(inState); if(inState!=null) { if (inState.getBoolean("bar", false)) { this.foo = (ArrayList<HashMap<String, Double>>) inState.getSerializable("foo"); } } }
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