My Android application has an ActionBar that changes which Fragment occupies a certain FrameLayout. I am trying to use onSaveInstanceState to save the state of a Fragment when the tab is changed, so that it can be recovered in onCreateView.
The problem is, onSaveInstanceState is never called. The Fragment‘s onDestroyView and onCreateView methods are called, but the Bundle supplied to onCreateView remains null.
Can someone please explain to me when onSaveInstanceState is actually called, how I can make sure it gets called when switching tabs, or the best practice for saving and restoring the state of a Fragment when it is detached and re-attached?
Fragment:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.event_log, container, false);
// Retrieve saved state
if (savedInstanceState != null){
System.out.println("log retrieved");
} else {
System.out.println("log null");
}
return view;
}
@Override
public void onSaveInstanceState(Bundle outState) {
System.out.println("log saved");
super.onSaveInstanceState(outState);
// more code
}
Activity:
/**
* Detach the current Fragment, because another one is being attached.
*/
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (tab.getText().equals(getString(R.string.tab_events))){
if (frEventLog != null) {
ft.detach(frEventLog);
}
}
Fragment#onSaveInstanceStateis only called when theActivityhosting theFragmentis destroyed AND there is a chance that you can come back to the same activity AND the fragment is still added to theFragmentManager. The most common case would be screen rotation.I think your
Fragmentwill also need to dosetRetainInstance(true)inonCreatefor example. Not exactly sure about that point though.You should also see this method being called when you press the home button for example. That will destroy the activity but you can go back to it by using the task list for example.
If you just
detach()the fragment all you need to do to get it back is to ask theFragmentManagerfor it.There are two examples you should have a look at:
ActionBarFragmentTabs andTabHostFragmentTabsThe
TabHostexample usesto find the instances of previously added
Fragments, works until youremove()aFragmentRegarding
onCreateView/onDestroyView: That is called once a fragment gets detached because the next time you attach it needs to create a newView. Note thatFragment#onDetached()is not called when youdetach()the fragment because it is still attached to theActivity. It is only detached from the view-hierarchy.There is another nice example on how to retain fragment state / how to use fragments to retain state in Android Training – Caching Bitmaps.
That example is missing a critical line though: