Android - Save/Restore Fragment State

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.

How to save state in fragment

Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null.

FYI : this is a sample code. Just for your reference.

public class MainFragment extends Fragment {
private String title;
private double rating;
private int year;

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);

savedInstanceState.putString(TITLE, "Gladiator");
savedInstanceState.putDouble(RATING, 8.5);
savedInstanceState.putInt(YEAR, 2000);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

title = savedInstanceState.getString(TITLE);
rating = savedInstanceState.getDouble(RATING);
year = savedInstanceState.getInt(YEAR);
}
}

FYI : This really a good thread check this also Once for all, how to correctly save instance state of Fragments in back stack?

Save and restore fragment state

Add Your fragment to back stack using addToBackStack("YOUTAG") like this in all your fragments :

android.support.v4.app.FragmentTransaction FT;
FT = getActivity().getSupportFragmentManager().beginTransaction();
FT.replace(R.id.main_container, new Register_Page6()).addToBackStack("FragmentName");
FT.commit();

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.

Save/Restore fragments state android

To achieve the thing which you want, you should use integer value to store the current position in your ViewPager, and after that use this value to set the right position to your ViewPager.

For example do something like this in your FragmentActivity:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("mMyCurrentPosition", mPager.getPosition());
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mMyCurrentPosition = savedInstanceState.getInt("mMyCurrentPosition");
// where mMyCurrentPosition should be a public value in your activity.
}

which will saved your ViewPager's last position. And after that in your onResume() for example you can check

if(mMyCurrentPosition != 0){
mPager.setCurrentItem(mMyCurrentPosition);
}

I think this should work , it's not a good practice to save images / bitmaps in bundle (and I don't think you are able to do it).

Save/Restore Fragment state with RecyclerView in Android

The problem is on your onResume method. You are not adding an Adapter and a LayoutManager to the RecylerView so it can't display the data. Try moving the RecylerView initalization code from the onClickListener to your onResume method:

 recyclerView = view!!.findViewById(R.id.posts_recycle_view)
val layoutManager = LinearLayoutManager(this.activity!!)
recyclerView.layoutManager = layoutManager
val adapter = PostsAdapter(posts)
recyclerView.adapter = adapter

Although having this initialization code in your onCreateView method would be better since it's the first lifecycle method called when a fragment returns to the front view from the backstack.

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);
}

}

Saving and restoring fragment state in viewpager

Use mViewPager.setOffscreenPageLimit(noOfPageYouWantToKeepInMemory);

Android: saving and restoring the state of a fragment

The example from the Android documentation shows the values being restored in the fragment's onActivityCreated() method. See the example at the bottom of this page: http://developer.android.com/guide/components/fragments.html#Lifecycle.



Related Topics



Leave a reply



Submit