Skip to content

Instantly share code, notes, and snippets.

@curioustechizen
Last active June 17, 2018 09:56
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save curioustechizen/6ed0981b013f63236f0b to your computer and use it in GitHub Desktop.
Save curioustechizen/6ed0981b013f63236f0b to your computer and use it in GitHub Desktop.
StateSavingArrayAdapter: An ArrayAdapter that knows how to save/restore its own state.
/**
* <p>
* An {@code ArrayAdapter} that also knows how to save and restore its state.
* Basically all it does is save/restore the array of objects being managed by
* the Adapter.
* </p>
*
* <p>
* Note that this only saves the items and not things like checked item
* positions. Those belong to the {@link ListView} itself. Consider using
* {@link ListView#onSaveInstanceState()} and
* {@link ListView#onRestoreInstanceState(Parcelable)} for this purpose.
* </p>
*
*
* @author Kiran Rao
*
* @param <T>
* The type of objects managed by this Adapter. Note that it must be a
* Parcelable.
*/
public class StateSavingArrayAdapter<T extends Parcelable> extends
ArrayAdapter<T> {
private static final String KEY_ADAPTER_STATE = "StateSavingArrayAdapter.KEY_ADAPTER_STATE";
/**
* Saves the instance state of this {@link ArrayAdapter}. It saves the array
* of currently managed by this adapter
*
* @param outState
* The bundle into which the state is saved
*/
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList(KEY_ADAPTER_STATE, getAllItems());
}
/**
* Restore the instance state of the {@link ArrayAdapter}. It re-initializes
* the array of objects being managed by this adapter with the state retrieved
* from {@code savedInstanceState}
*
* @param savedInstanceState
* The bundle containing the previously saved state
*/
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(KEY_ADAPTER_STATE)) {
ArrayList<T> objects = savedInstanceState
.getParcelableArrayList(KEY_ADAPTER_STATE);
setItems(objects);
}
}
/**
* Gets all the items in this adapter as an {@code ArrayList}
*/
public ArrayList<T> getAllItems(){
ArrayList<T> objects = new ArrayList<T>(getCount());
for (int i = 0; i < getCount(); i++) {
objects.add(getItem(i));
}
return objects;
}
/*
* Replaces the items in the adapter with those in this list
* @param items The items to set into the adapter.
*/
public void setItems(ArrayList<T> items){
clear();
addAll(items);
}
/* Constructors and other boilerplate */
public StateSavingArrayAdapter(Context context, int resource) {
super(context, resource);
}
public StateSavingArrayAdapter(Context context, int resource,
int textViewResourceId) {
super(context, resource, textViewResourceId);
}
public StateSavingArrayAdapter(Context context, int resource, T[] objects) {
super(context, resource, objects);
}
public StateSavingArrayAdapter(Context context, int resource, List<T> objects) {
super(context, resource, objects);
}
public StateSavingArrayAdapter(Context context, int resource,
int textViewResourceId, T[] objects) {
super(context, resource, textViewResourceId, objects);
}
public StateSavingArrayAdapter(Context context, int resource,
int textViewResourceId, List<T> objects) {
super(context, resource, textViewResourceId, objects);
}
}
/*
* Illustration of how to use the StateSavingArrayAdapter.
*
* First, have your custom Adapter extend StateSavingArrayAdapter instead of ArrayAdapter.
* Then, call the appropriate methods in onSaveInstanceState/ onCreate as illustrated here.
*
* This example also illustrates how you would save the ListView state itself so that your checked items are remembered.
*/
public class StateSavingMainActivity extends Activity {
private UserAdapter mAdapter;
private ListView mListView;
private static final String KEY_LIST_VIEW_STATE = "KEY_LIST_VIEW_STATE";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* Create the mAdapter instance here. For example, mAdapter = new UserAdapter(this); */
/* Then, restore the adapter state as follows */
if (savedInstanceState != null) {
mAdapter.onRestoreInstanceState(savedInstanceState);
}
mListView = (ListView) findViewById(android.R.id.list);
if (savedInstanceState != null
&& savedInstanceState.containsKey(KEY_LIST_VIEW_STATE)) {
mListView.onRestoreInstanceState(savedInstanceState
.getParcelable(KEY_LIST_VIEW_STATE));
}
mListView.setAdapter(mAdapter);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mAdapter.onSaveInstanceState(outState);
outState
.putParcelable(KEY_LIST_VIEW_STATE, mListView.onSaveInstanceState());
}
private class UserAdapter extends StateSavingArrayAdapter<User> {
/* Add appropriate constructors */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/*
* Inflate your XML and return the view here
*/
return super.getView(position, convertView, parent);
}
}
}
@ihajat
Copy link

ihajat commented Oct 29, 2015

Have you got sample code that shows how this class is used?

@curioustechizen
Copy link
Author

@ihajat
The StateSavingMainActivity class above is an example of how it is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment