ChatGPT解决这个技术问题 Extra ChatGPT

Listview Scroll to the end of the list after updating the list

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

try doing this it works...messagesListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); messagesListView.setStackFromBottom(true);
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.

s
sulai

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);
        }
    });
}

@Bhupendra that is not necessary. You can do without thread too, as shown in Warting's answer.
@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.
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 animation
@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.
you can also use myListView.smoothScrollToPosition(myListAdapter.getCount()-1); for smooth scrolling
J
Jonas Czech

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" />

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.
Quick question: Any way I can get the scrolling to be animated? Cause currently when I notifyDataSetChanged() it jumps with no animation?!?
@Georg Have you disabled animations in Developer Options on your device perhaps ?
W
Wärting

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);    
    }
});

M
Mason Lee

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);

This is a great solution. Simple, one line.
K
Klatschen

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


P
Pratik Butani

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.


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.
P
Plugie

I use

setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);

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


Call getListView().smoothScrollToPosition(getListAdapter.getCount() - 1); in onstart to scroll to the bottom in the begining of the activity.
u
ucMedia

The simplest solution is :

    listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
    listView.setStackFromBottom(true);

R
Romain Guy

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?


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.
Transcript mode is actually disabled by the SMS app. I can't remember why exactly.