javaandroidlistviewandroid-fragmentsonrestoreinstancestate

How to use onSaveInstanceState and onRestoreInstanceState methods with fragments?


I have two Fragments. One of it has one EditText and one Button. The other one has only one ListView. How to save datas which are in ListView in case of any change in the orientation of emulator?

My problem is that I don't know how to save and restore my ListView when I rotate the emulator's screen. Where should I put the onSaveInstanceState and onRestoreInstanceState methods and how to use them?

MainActivity.java

    public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener {

private ArrayList<String> todoItems;
private ArrayAdapter<String> adapter;

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

    FragmentManager fm = getFragmentManager();

    ToDoListFragment listToDo = new ToDoListFragment();
    listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);
    todoItems = new ArrayList<String>();
    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
    listToDo.setListAdapter(adapter);
}

public void OnToDoAdded(String newToDo) {
    todoItems.add(newToDo);
    adapter.notifyDataSetChanged();

}

AddToDoFragment.java

public class AddToDoFragment extends Fragment {

public interface OnToDoAddedListener {

    public void OnToDoAdded (String newToDo);

}

private OnToDoAddedListener onToDoAddedListener;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        final Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.add_to_do_fragment, container, false);

    final EditText edittext = (EditText) view.findViewById(R.id.editText);
    final Button button = (Button) view.findViewById(R.id.addButton);
    button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            String text = edittext.getText().toString();
            onToDoAddedListener.OnToDoAdded(text);
            edittext.setText("");
        }
    });

    return view;

}

 @Override
    public void onAttach(Activity activity) {
      super.onAttach(activity);
      if (activity instanceof OnToDoAddedListener) {
        onToDoAddedListener = (OnToDoAddedListener) activity;
      } else {
        throw new ClassCastException(activity.toString()
            + " must implemenet AddToDoFragment.OnToDoAddedListener");
      }
    }
   }

ToDoListFragment.java

public class ToDoListFragment extends ListFragment {
}

Solution

  • You will want to override the onSaveInstanceState method of your activity so that you know when the state needs to be saved. Then you will also need to update your onCreate method to check if the savedInstanceState is null. If it is null then the activity hasn't been initiated. This is the example for your MainActivity class, and you can go from there:

    MainActivity.java

    public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener {
    
    private ArrayList<String> todoItems;
    private ArrayAdapter<String> adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        if(savedInstanceState == null) {
            todoItems = new ArrayList<String>();
        } else {
            todoItems = savedInstanceState.getStringArrayList("todoItemTag");//the tag must match what the variable was saved with
        }
    
        FragmentManager fm = getFragmentManager();
    
        ToDoListFragment listToDo = new ToDoListFragment();
        listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
        listToDo.setListAdapter(adapter);
    }
    
    public void OnToDoAdded(String newToDo) {
        todoItems.add(newToDo);
        adapter.notifyDataSetChanged();
    
    }
    
    //Saving the instance by overriding this function
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    
        outState.putStringArrayList("todoItemTag", todoItems);//it would be advised to make the tags a static final String
    }
    

    Hopefully this helps!

    PS: I don't think the onRestoreInstanceState method is really necessary. I guess I have never used it before. I believe that you should be able to provide the same functionality with the null check in the onCreate method.