Maintain/Save/Restore scroll position when returning to a ListView Maintain/Save/Restore scroll position when returning to a ListView android android

Maintain/Save/Restore scroll position when returning to a ListView


Try this:

// save index and top positionint index = mList.getFirstVisiblePosition();View v = mList.getChildAt(0);int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());// ...// restore index and positionmList.setSelectionFromTop(index, top);

Explanation:

ListView.getFirstVisiblePosition() returns the top visible list item. But this item may be partially scrolled out of view, and if you want to restore the exact scroll position of the list you need to get this offset. So ListView.getChildAt(0) returns the View for the top list item, and then View.getTop() - mList.getPaddingTop() returns its relative offset from the top of the ListView. Then, to restore the ListView's scroll position, we call ListView.setSelectionFromTop() with the index of the item we want and an offset to position its top edge from the top of the ListView.


Parcelable state;@Overridepublic void onPause() {        // Save ListView state @ onPause    Log.d(TAG, "saving listview state");    state = listView.onSaveInstanceState();    super.onPause();}...@Overridepublic void onViewCreated(final View view, Bundle savedInstanceState) {    super.onViewCreated(view, savedInstanceState);    // Set new items    listView.setAdapter(adapter);    ...    // Restore previous state (including selected item index and scroll position)    if(state != null) {        Log.d(TAG, "trying to restore listview state");        listView.onRestoreInstanceState(state);    }}


I adopted the solution suggested by @(Kirk Woll), and it works for me. I have also seen in the Android source code for the "Contacts" app, that they use a similar technique. I would like to add some more details:On top on my ListActivity-derived class:

private static final String LIST_STATE = "listState";private Parcelable mListState = null;

Then, some method overrides:

@Overrideprotected void onRestoreInstanceState(Bundle state) {    super.onRestoreInstanceState(state);    mListState = state.getParcelable(LIST_STATE);}@Overrideprotected void onResume() {    super.onResume();    loadData();    if (mListState != null)        getListView().onRestoreInstanceState(mListState);    mListState = null;}@Overrideprotected void onSaveInstanceState(Bundle state) {    super.onSaveInstanceState(state);    mListState = getListView().onSaveInstanceState();    state.putParcelable(LIST_STATE, mListState);}

Of course "loadData" is my function to retrieve data from the DB and put it onto the list.

On my Froyo device, this works both when you change the phone orientation, and when you edit an item and go back to the list.