Listview Scroll to the end of the list after updating the list
Asked Answered
L

9

299

I would like to make sure that the list is scrolled all the way to the bottom, after I have updated the listview by using listAdapter, so that it displays the last element entered in the list. How can I do this ?

I tried this but no luck:

lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

thank you

Legislature answered 31/8, 2010 at 6:29 Comment(2)
try doing this it works...messagesListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); messagesListView.setStackFromBottom(true);Japeth
lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL) only ensures that listView will be scrolled down after calling adapter.notifyDataSetChanged. If this is not working, try to define this property in xml as you can see in posts below.Literalism
C
428

Supposing you know when the list data has changed, you can manually tell the list to scroll to the bottom by setting the list selection to the last row. Something like:

private void scrollMyListViewToBottom() {
    myListView.post(new Runnable() {
        @Override
        public void run() {
            // Select the last row so it will scroll into view...
            myListView.setSelection(myListAdapter.getCount() - 1);
        }
    });
}
Corporative answered 11/8, 2011 at 20:22 Comment(7)
@Bhupendra that is not necessary. You can do without thread too, as shown in Warting's answer.Kerwinn
@Bhupendra setSelection() updates the UI. By calling post(Runnable) on the view, you ensure the Runnable code is run on the android UI thread. Generally do it this way unless you know you're already on the UI thread, or are ensuring that by some other means.Corporative
it also seems that using post on a newly set adapter causes scroll animation while ensuring to be in main thread and using setSelection immediately after setting the adapter causes no scroll animationWoof
This answer is not good enough if the last item is too large, it will scroll to the head of the last item. Use setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL) and setStackFromBottom(true) for better result.Griz
@SaifHamed as commented by Mason Lee on the answer of Kevin, this also causes short lists to have "empty" space at the top of the view instead of the bottom which is most likely not the intended behaviour.Spitsbergen
you can also use myListView.smoothScrollToPosition(myListAdapter.getCount()-1); for smooth scrollingNesbitt
@MasonLee can you please tell me how can 1 fix the problem described by Saif Hamed without having to setStackFromBottom(true)?Jampack
C
240

You need to use these parameters in your list view:

  • Scroll lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

  • Set the head of the list to it bottom lv.setStackFromBottom(true);

You can also set these parameters in XML, eg. like this:

<ListView
   ...
   android:transcriptMode="alwaysScroll"
   android:stackFromBottom="true" />
Catrinacatriona answered 27/11, 2010 at 22:43 Comment(3)
Note that with this approach, rows "stack from the bottom" of the view as they are added. This means that short lists will have "empty" space at the top of the view instead of the bottom, which is not always what one wants.Corporative
Quick question: Any way I can get the scrolling to be animated? Cause currently when I notifyDataSetChanged() it jumps with no animation?!?Malvaceous
@Malvaceous Have you disabled animations in Developer Options on your device perhaps ?Standridge
B
37

A combination of TRANSCRIPT_MODE_ALWAYS_SCROLL and setSelection made it work for me

ChatAdapter adapter = new ChatAdapter(this);

ListView lv = (ListView) findViewById(R.id.chatList);
lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
lv.setAdapter(adapter);

adapter.registerDataSetObserver(new DataSetObserver() {
    @Override
    public void onChanged() {
        super.onChanged();
        lv.setSelection(adapter.getCount() - 1);    
    }
});
Burundi answered 27/12, 2011 at 9:43 Comment(0)
A
31

I've had success using this in response to a button click, so I guess that you can use it too after updating your contents:

myListView.smoothScrollToPosition(theListAdapter.getCount() -1);
Avens answered 24/1, 2015 at 16:53 Comment(1)
This is a great solution. Simple, one line.Chevy
E
11

To get this in a ListFragment:

getListView().setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); 
getListView().setStackFromBottom(true);`

Added this answer because if someone do a google search for same problem with ListFragment he just finds this..

Regards

Exposed answered 7/4, 2016 at 7:26 Comment(0)
B
9

Using : Set the head of the list to it bottom lv.setStackFromBottom(true);

Worked for me and the list is scrolled to the bottom automatically when it is first brought into visibility. The list then scrolls as it should with TRANSCRIPT_MODE_ALWAYS_SCROLL.

Baronetcy answered 28/2, 2011 at 1:58 Comment(1)
Note that with this approach, rows "stack from the bottom" of the view as they are added. This means that short lists will have "empty" space at the top of the view instead of the bottom.Corporative
F
5

I use

setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);

to add entries at the bottom, and older entries scroll off the top, like a chat transcript

Farhi answered 16/8, 2014 at 14:13 Comment(1)
Call getListView().smoothScrollToPosition(getListAdapter.getCount() - 1); in onstart to scroll to the bottom in the begining of the activity.Themistocles
D
3

The transcript mode is what you want and is used by Google Talk and the SMS/MMS application. Are you correctly calling notifyDatasetChanged() on your adapter when you add items?

Discommon answered 31/8, 2010 at 6:42 Comment(2)
yes I am. the list correctly gets updated, but always start from the top. I just need it to add the new item and always scroll to the end of the list.Legislature
Transcript mode is actually disabled by the SMS app. I can't remember why exactly.Stepper
H
3

The simplest solution is :

    listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
    listView.setStackFromBottom(true);
Haily answered 29/12, 2018 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.