Android - save/restore fragment state

Stanete picture Stanete · Mar 19, 2014 · Viewed 128.1k times · Source

I have an Activity in which I go through several fragments. In every fragment I have several views (EditText, ListView, Map, etc).

How can I save the instance of the fragment that is shown at that moment? I need it to work when the activity is onPause() --> onResume(). Also I need it to work when I return from another fragment (pop from backstack).

From the main Activity I call the first fragment, then from the the fragment I call the next one.

Code for my Activity:

public class Activity_Main extends FragmentActivity{

public static Fragment_1 fragment_1;
public static Fragment_2 fragment_2;
public static Fragment_3 fragment_3;
public static FragmentManager fragmentManager;

@Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

     fragment_1 = new Fragment_1();

     fragment_2 = new Fragment_2();

     fragment_3 = new Fragment_3();

     fragmentManager = getSupportFragmentManager();
     FragmentTransaction transaction_1 = fragmentManager.beginTransaction();
     transaction_1.replace(R.id.content_frame, fragment_1);
     transaction_1.commit();
}}

Then here is the code for one of my fragments:

public class Fragment_1 extends Fragment {

      private EditText title;
      private Button go_next;


      @Override
      public View onCreateView(final LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {

            View rootView = inflater.inflate(R.layout.fragment_1,
            container, false);

            title = (EditText) rootView.findViewById(R.id.title);

            go_next = (Button) rootView.findViewById(R.id.go_next);

            image.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View v) {

                 FragmentTransaction transaction_2 = Activity_Main.fragmentManager
                .beginTransaction();

                 transaction_2.replace(R.id.content_frame,
                  Activity_Main.fragment_2);
                 transaction_2.addToBackStack(null);
                 transaction_2.commit();  

            });
        }}

I have searched a lot of information but nothing clear. Can somebody give a clear solution and an example, please ?

Answer

Kirill Rakhman picture Kirill Rakhman · Mar 19, 2014

When a fragment is moved to the backstack, it isn't destroyed. All the instance variables remain there. So this is the place to save your data. In onActivityCreated you check the following conditions:

  1. Is the bundle != null? If yes, that's where the data is saved (probably orientation change).
  2. Is there data saved in instance variables? If yes, restore your state from them (or maybe do nothing, because everything is as it should be).
  3. Otherwise your fragment is shown for the first time, create everything anew.

Edit: Here's an example

public class ExampleFragment extends Fragment {
    private List<String> myData;

    @Override
    public void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable("list", (Serializable) myData);
    }

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

        if (savedInstanceState != null) {
            //probably orientation change
            myData = (List<String>) savedInstanceState.getSerializable("list");
        } else {
            if (myData != null) {
                //returning from backstack, data is fine, do nothing
            } else {
                //newly created, compute data
                myData = computeData();
            }
        }
    }
}