165

How can I programmatically scroll to a specific position in a ListView?

For example, I have a String[] {A,B,C,D....}, and I need to set the top visible item of the ListView to the index 21 of my String[].

Beryllium
  • 12,808
  • 10
  • 56
  • 86
Maxime
  • 3,167
  • 7
  • 26
  • 33

13 Answers13

402

For a direct scroll:

getListView().setSelection(21);

For a smooth scroll:

getListView().smoothScrollToPosition(21);
HandlerExploit
  • 8,131
  • 4
  • 31
  • 50
65

For a SmoothScroll with Scroll duration:

getListView().smoothScrollToPositionFromTop(position,offset,duration);

Parameters
position -> Position to scroll to
offset ---->Desired distance in pixels of position from the top of the view when scrolling is finished
duration-> Number of milliseconds to use for the scroll

Note: From API 11.

HandlerExploit's answer was what I was looking for, but My listview is quite lengthy and also with alphabet scroller. Then I found that the same function can take other parameters as well :)


Edit:(From AFDs suggestion)

To position the current selection:

int h1 = mListView.getHeight();
int h2 = listViewRow.getHeight();

mListView.smoothScrollToPositionFromTop(position, h1/2 - h2/2, duration);  
Community
  • 1
  • 1
amalBit
  • 12,041
  • 6
  • 77
  • 94
10

Put your code in handler as follows,

public void timerDelayRunForScroll(long time) {
        Handler handler = new Handler(); 
        handler.postDelayed(new Runnable() {           
            public void run() {   
                try {
                    lstView.smoothScrollToPosition(YOUR_POSITION);
                } catch (Exception e) {}
            }
        }, time); 
    }

and then call this method like,

timerDelayRunForScroll(100);

CHEERS!!!

Melbourne Lopes
  • 4,817
  • 2
  • 34
  • 36
8

The Listview scroll will be positioned to top by default, but want to scroll if not visible then use this:

if (listView1.getFirstVisiblePosition() > position || listView1.getLastVisiblePosition() < position)
            listView1.setSelection(position);
dur
  • 15,689
  • 25
  • 79
  • 125
Zalak Gajjar
  • 81
  • 1
  • 4
7

I have set OnGroupExpandListener and override onGroupExpand() as:

and use setSelectionFromTop() method which Sets the selected item and positions the selection y pixels from the top edge of the ListView. (If in touch mode, the item will not be selected but it will still be positioned appropriately.) (android docs)

    yourlist.setOnGroupExpandListener (new ExpandableListView.OnGroupExpandListener()
    {

        @Override
        public void onGroupExpand(int groupPosition) {

            expList.setSelectionFromTop(groupPosition, 0);
            //your other code
        }
    });
tkanzakic
  • 5,499
  • 16
  • 34
  • 41
Inet Labs
  • 71
  • 1
  • 1
  • I need to scroll another view simultaneously while scrolling lisview. Using setSelectionFromTop on listview for scrolling blocks the UI thread which makes the scrolling of another view slow. Can you give some suggestion how to do it? – VijayRaj Nov 27 '14 at 09:20
5

If someone looking for a similar functionality like Gmail app,

The Listview scroll will be positioned to top by default. Thanks for the hint. amalBit. Just subtract it. That's it.

 Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            int h1 = mDrawerList.getHeight();
            int h2 = header.getHeight();
            mDrawerList.smoothScrollToPosition(h2-h1);
        }
    }, 1000);
EngineSense
  • 3,266
  • 8
  • 28
  • 44
5

If you want to jump directly to the desired position in a listView just use

listView.setSelection(int position);

and if you want to jump smoothly to the desired position in listView just use

listView.smoothScrollToPosition(int position);

Vijay
  • 608
  • 7
  • 11
4

Handling listView scrolling using UP/ Down using.button

If someone is interested in handling listView one row up/down using button. then.

public View.OnClickListener onChk = new View.OnClickListener() {
             public void onClick(View v) {

                 int index = list.getFirstVisiblePosition();
                 getListView().smoothScrollToPosition(index+1); // For increment. 

}
});
Zar E Ahmer
  • 33,936
  • 20
  • 234
  • 300
  • I give you the up vote just because you are the only one that showed a way to get the current position, but you should improve example. – Panciz Jun 05 '15 at 13:57
3

This is what worked for me. Combination of answers by amalBit & Melbourne Lopes

public void timerDelayRunForScroll(long time) {
    Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() {           
        public void run() {   
            try {
                  int h1 = mListView.getHeight();
                  int h2 = v.getHeight();

                  mListView.smoothScrollToPositionFromTop(YOUR_POSITION, h1/2 - h2/2, 500);  

            } catch (Exception e) {}
        }
    }, time); 
}

and then call this method like:

timerDelayRunForScroll(400);
Pang
  • 9,564
  • 146
  • 81
  • 122
2

it is easy list-view.set selection(you pos); or you can save your position with SharedPreference and when you start activity it get preferences and setSeletion to that int

Zain
  • 37,492
  • 7
  • 60
  • 84
Bagher
  • 29
  • 3
  • all i wanted to do was automatically move to the top of the list, without any scrolling animation...this worked perfectly for that – RH201 May 31 '18 at 18:58
2

-If you just want the list to scroll up\dawn to a specific position:

myListView.smoothScrollToPosition(i);

-if you want to get the position of a specific item in myListView:

myListView.getItemAtPosition(i);

-also this myListView.getVerticalScrollbarPosition(i);can helps you.

Good Luck :)

Basil Rawa
  • 109
  • 1
  • 5
2

You need two things to precisely define the scroll position of a listView:

To get the current listView Scroll position:

int firstVisiblePosition = listView.getFirstVisiblePosition(); 
int topEdge=listView.getChildAt(0).getTop(); //This gives how much the top view has been scrolled.

To set the listView Scroll position:

listView.setSelectionFromTop(firstVisiblePosition,0);
// Note the '-' sign for scrollTo.. 
listView.scrollTo(0,-topEdge);
-1

I found this solution to allow the scroll up and down using two different buttons.

As suggested by @Nepster I implement the scroll programmatically using the getFirstVisiblePosition() and getLastVisiblePosition() to get the current position.

final ListView lwresult = (ListView) findViewById(R.id.rds_rdi_mat_list);
    .....

        if (list.size() > 0) {
            ImageButton bnt = (ImageButton) findViewById(R.id.down_action);
            bnt.setVisibility(View.VISIBLE);
            bnt.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(lwresult.getLastVisiblePosition()<lwresult.getAdapter().getCount()){
                        lwresult.smoothScrollToPosition(lwresult.getLastVisiblePosition()+5);
                    }else{
                        lwresult.smoothScrollToPosition(lwresult.getAdapter().getCount());

                    }
                }
            });
            bnt = (ImageButton) findViewById(R.id.up_action);
            bnt.setVisibility(View.VISIBLE);

            bnt.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if(lwresult.getFirstVisiblePosition()>0){
                        lwresult.smoothScrollToPosition(lwresult.getFirstVisiblePosition()-5);
                    }else{
                        lwresult.smoothScrollToPosition(0);
                    }

                }
            });
        }
Panciz
  • 2,183
  • 2
  • 30
  • 54