See Maintain/Save/Restore scroll position when returning to a ListView for more discussion and options, but the following method worked for me:
Make a class level variable to save the scroll position and also a key for the state:
static final String STATE_SCROLL_POSITION = "scrollPosition";
int savedPosition = 0;
Override onSaveInstanceState
to get the current position before rotation.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
int currentPosition = lvTests.getFirstVisiblePosition();
savedInstanceState.putInt(STATE_SCROLL_POSITION,
currentPosition);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Then get the saved position back when the activity is recreated:
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
savedPosition = savedInstanceState
.getInt(STATE_SCROLL_POSITION);
listView.setSelection(savedPosition);
}
In one of my activities I used an AsyncTask
(as a subclass in my activity) to populate my ListView
and had to restore the position in the onPostExecute
method.
@Override
protected void onPostExecute(ArrayList<Test> result) {
adapter = new MyListAdapter(getApplicationContext(), result);
lvTests.setAdapter(adapter);
lvTests.setSelection(savedPosition); // position is restored here
}
If you populate your listview in another way then just make sure you set the scroll position after you set the adapter.
I did these within an Activity but it should work with fragments, too.