Using onSaveInstanceState with fragments in backstack?
It is possible that your member variables don't exist anymore because the FragmentManager
in your Activity
is dying with all of your fragments.
You need to override the method onSaveInstanceState
of your Activity
class as well, because you need to save the Activity
state before you save the Fragments
state.
As the documentation says:
There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state.
UPDATE
In your Activity
onSaveInstanceState
and onRestoreInstanceState
, try saving you Fragment
references and then restore them with something like this:
public void onSaveInstanceState(Bundle outState){
getFragmentManager().putFragment(outState, "myfragment", myfragment);
}
public void onRestoreInstanceState(Bundle inState){
myFragment = getFragmentManager().getFragment(inState, "myfragment");
}
Tell me then if you had luck! :-)
How to correctly save instance state of Fragments in back stack?
To correctly save the instance state of Fragment
you should do the following:
1. In the fragment, save instance state by overriding onSaveInstanceState()
and restore in onActivityCreated()
:
class MyFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
...
if (savedInstanceState != null) {
//Restore the fragment's state here
}
}
...
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's state here
}
}
2. And important point, in the activity, you have to save the fragment's instance in onSaveInstanceState()
and restore in onCreate()
.
class MyActivity extends Activity {
private MyFragment
public void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
//Restore the fragment's instance
mMyFragment = getSupportFragmentManager().getFragment(savedInstanceState, "myFragmentName");
...
}
...
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's instance
getSupportFragmentManager().putFragment(outState, "myFragmentName", mMyFragment);
}
}
All fragments on backstack, have nulls in onSaveInstanceState, after rotation
I have exactly the same problem.
Lets say I have Frag A, calling Frag B
When I get from Frag A to Frag B, Frag A exists on backstack and is not showing. While in Frag B, on a first rotate the onSavedInstanceState()
is being called for Frag A and it works fine, since the Frag A on back stack exists and all the data was there..
When I rotate the device again in Frag B, the Frag A onSavedInstanceState()
is called again for some unknown reason.. between these calls a restore was never issued since onCreateView has not been called since Frag A is not visible.
Why it is doing that I have 0 clue.
What I do, is I check if Bundle is empty (and bundle does exist after 2nd rotate, its just empty) and if it is, I try to recreate Frag from scratch, which means reloading fresh data from a request... which is not the best solution..
Unable to save Fragment state with onSaveInstanceState
I solved it, the problem was here
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (savedInstanceState != null) {
dataFragment = (InputDataFragment) getSupportFragmentManager().getFragment(savedInstanceState, "dataFragment");
} else {
dataFragment = new InputDataFragment();
}
fragmentTransaction.add(R.id.container, dataFragment);
fragmentTransaction.commit();
}
When I'm in ResultsFragment and rotate the device, Activity onCreate
method is called. Even though I got the previous InputDataFragment back from Bundle, calling FragmentTransaction.add()
caused the loss of the data.
Moving FragmentTransaction
code to the case where savedInstanceState == null was the solution.
Saving and restoring state using fragments
You want to save the value of your current checked state in onSaveInstanceState
.
Something like this:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(CHECK_BOX_STATE, cb.getChecked());
}
and then when your view is created you want to get the value if it's present. And set your CheckBox
state with it.
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fifth_layout, container, false);
cb = (CheckBox) view.findViewById(R.id.checkBox);
if (savedInstanceState != null) {
// Restore last state for checked position.
boolean checked = savedInstanceState.getBoolean(CHECK_BOX_STATE, false);
cb.setChecked(checked);
}
return view;
}
EDIT:
When you add the fragment, make sure to add it with a tag or id so that you can retrieve the same instance.
You could do a helper method to retrieve fragment and set the fragment.
private void setFragment(String tag, Fragment newFragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment savedFragment = fm.getFragmentByTag(tag);
fm.replace(R.id.container, savedFragment != null ? savedFragment : newFragment, tag);
fm.commit();
}
so you your switch
you can call the helper method instead.
switch (position) {
case 0:
setFragment("A", new FragmentA());
break;
....
}
Note: This is just an example not best practice since you are creating new fragments every time in your switch case
now anyways. But it might point you in the right direction.
Related Topics
How to Use Front and Back Camera at Same Time in Android
Validation Allow Only Number and Characters in Edit Text in Android
Proguard with Ormlite on Android
How Could I Filter the Listview Using Baseadapter
What's the Maximum Size for an Android Shared Preference Value
Get Nfc Tag with Ndef Android Application Record (Aar)
Gridlayout and Row/Column Span Woe
How to Change Toolbar Home Icon Color
Animate Progressbar Update in Android
Getting Nosuchfielderror Instance Org/Apache/Http/Message/Basicheadervalueparser
Continuous Speech Recognition Android
Firebase Onmessagereceived Not Called When App Is in the Background
Android Recyclerview Findviewholderforadapterposition Returns Null
Android App Enable Nfc Only for One Activity