views:

347

answers:

2

Hi,

I have a long listView that the user scrolls around and then returns to the previous menu . What I want is that when the user opens this list View again the list to be scrolled to where the it was previously left. Any ideas on how this can be achieved ?

+5  A: 

A very simple way:

/** Save the position **/
int currentPosition = listView.getFirstVisiblePosition();

//Here u should save the currentPosition anywhere

/** Restore the previus saved position **/
listView.setSelection(savedPosition);

The method setSelection will reset the list to the supplied item. If not in touch mode the item will actually be selected if in touch mode the item will only be positioned on screen.

A more complicated approach:

listView.setOnScrollListener(this);
//Implements the interface:
@Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        mCurrentX = view.getScrollX();
        mCurrentY = view.getScrollY();
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {}



//Save anywere the x and the y

/** Restore: **/
listView.scrollTo(savedX, savedY);
Francesco
there was an error in your answer. The method is called setSelection
Janusz
Ty for the correction!
Francesco
The idea works well, but there is a pseudo problem.The first visible position might be shown only a little bit, (maybe just a small part of the row) , and setSelection() set this row to be completely visible when the restore is made.
rantravee
Please take a look at my second option. I have just added it to my first answer
Francesco
view.getScrollX() and view.getScrollY() always return 0 !
rantravee
Returns 0 for me too, I've been trying to do the second method for ages but always get 0. The first method is insufficient for large list items. Anybody?
HXCaine
Take a look at my (accepted) solution above using View.getChildAt() and View.getTop(). You can't use View.getScrollY() on a ListView because a ListView maintains its scrolling internally.
irlennard
+2  A: 

Try this:

// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();

// ...

// restore
mList.setSelectionFromTop(index, top);
irlennard
Not really understanding how this works. I'm using listView.getFirstVisiblePosition() only and understand that, but not sure what's going on here. Any chance of a brief explanation? :)
HXCaine
So 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() 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. All clear?
irlennard