Godfryd
Godfryd

Reputation: 479

Saving and restoring state using fragments

I'm trying to understand the process of saving and restoring state using fragments. I've created sliding navigation menu using it.

In one of the fragments there is this code:

public class FifthFragment extends Fragment {

    CheckBox cb;
    View view;

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

        view = inflater.inflate(R.layout.fifth_layout, container, false);
        cb = (CheckBox) view.findViewById(R.id.checkBox);
        return view;

    }

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

        if (savedInstanceState != null) {
            // Restore save state
        }

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // save state
    }

}

For example I want to save the state of the CheckBox before user exits the fragment and restore it when the fragment is created again. How to achieve this?

EDIT:

According to raxellson's answer I've changed my fragment to this:

public class FifthFragment extends Fragment {

    private static final String CHECK_BOX_STATE = "string";
    CheckBox cb;
    View view;

    @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) {
            Log.i("statenull", "null");
        }
        if (savedInstanceState != null) {
            // Restore last state for checked position.
            boolean checked = savedInstanceState.getBoolean(CHECK_BOX_STATE, false);
            cb.setChecked(checked);
        }

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(CHECK_BOX_STATE, cb.isChecked());
    }

}

I got logged I/statenull: null so savedInstanceState was not saved. What am I doing wrong?

Upvotes: 2

Views: 15942

Answers (2)

ATA UR RAHMAN
ATA UR RAHMAN

Reputation: 59

After see all the example. Here is the solution for save fragment state:

Two steps for this:

1.

String saveValue;
 
 
 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            saveValue = "";
        } else {

            saveValue = savedInstanceState.getString("saveInstance");
          

        }
    }
@Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        //save the values of fragment if destroy on second to back
        if (!saveValue.isEmpty())
            savedInstanceState.putString("saveInstance", saveValue);
       
    }

In onSaveInstanceState you can save your values. And after destroy fragment you can receive your values through onCreate.

Upvotes: 0

malmling
malmling

Reputation: 2518

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.

Upvotes: 5

Related Questions