Перегляд списку Прокрутіть до кінця списку після оновлення списку


292

Я хотів би переконатися, що список прокручується до кінця, після того як я оновив перегляд списку за допомогою listAdapter, щоб він відображав останній елемент, внесений до списку. Як я можу це зробити?

Я спробував це, але не пощастило:

lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

Дякую тобі


спробуйте це зробити, це працює ... messagesListView.setTranscriptMode (ListView.TRANSCRIPT_MODE_NORMAL); messagesListView.setStackFromBottom (вірно);
Супердев

lv.setTranscriptMode (ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL) гарантує лише те, що listView буде прокручено вниз після виклику adapter.notifyDataSetChanged. Якщо це не працює, спробуйте визначити це властивість у форматі xml, як ви можете бачити у публікаціях нижче.
tomm

Відповіді:


418

Припустимо, що ви знаєте, коли змінилися дані списку, ви можете вручну сказати списку прокручуватися донизу, встановивши вибір списку на останній рядок. Щось на зразок:

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, що не потрібно. Ви також можете обійтися без теми, як показано у відповіді Вартінга.
sagarpatidar

2
@Bhupendra setSelection () оновлює інтерфейс користувача. Викликаючи повідомлення (Runnable) на поданні, ви гарантуєте, що Runnable код запускається на потоці користувальницького інтерфейсу Android. Як правило, зробіть це так, якщо ви не знаєте, що вже перебуваєте в потоці користувальницького інтерфейсу, або не домагаєтесь цього іншим способом.
Мейсон Лі

5
також здається, що використання публікації на щойно встановленому адаптері викликає анімацію прокрутки, одночасно гарантуючи, що вона знаходиться в основній темі, а використання setSelection одразу після встановлення адаптера не викликає анімації прокрутки
Gianluca P.

1
@SaifHamed, як прокоментував Мейсон Лі у відповідь Кевіна, це також спричиняє короткі списки, які мають "порожнє" місце у верхній частині огляду, а не внизу, що, швидше за все, не має наміру поведінки.
тире

16
ви також можете використовувати myListView.smoothScrollToPosition (myListAdapter.getCount () - 1); для плавного прокрутки
Zar E Ahmer

238

Вам потрібно використовувати ці параметри у своєму списку списку:

  • Прокрутіть lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

  • Встановіть голову списку внизу lv.setStackFromBottom(true);

Ви також можете встановити ці параметри в XML, наприклад. подобається це:

<ListView
   ...
   android:transcriptMode="alwaysScroll"
   android:stackFromBottom="true" />

27
Зауважте, що при такому підході рядки "складаються знизу" подання у міру їх додавання. Це означає, що у коротких списках буде "порожнє" місце у верхній частині огляду замість нижнього, що не завжди є тим, що хочеться.
Мейсон Лі

2
Швидке запитання: Яким чином я можу змусити анімовувати прокрутку? Тому що в даний момент, коли я повідомляюDataSetChanged (), вона стрибає без анімації?!?
Георг

@Georg Чи можливо ви відключили анімацію в "Параметри розробника" на своєму пристрої?
JonasCz

35

Поєднання TRANSCRIPT_MODE_ALWAYS_SCROLL та setSelection змусило мене працювати

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

29

Я користувався цим у відповідь на натискання кнопки, тому, мабуть, ви можете використовувати його і після оновлення вмісту:

myListView.smoothScrollToPosition(theListAdapter.getCount() -1);

1
Це чудове рішення. Простий, один рядок.
Джош Ларсон

12

Щоб отримати це у ListFragment:

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

Додав цю відповідь, тому що якщо хтось шукає Google за тією ж проблемою з ListFragment, він просто знаходить це.

З повагою


9

Використання: Встановіть верхню частину списку внизу lv.setStackFromBottom(true);

Працював для мене, і список автоматично прокручується донизу, коли він вперше стає видимим. Потім список прокручується як слід TRANSCRIPT_MODE_ALWAYS_SCROLL.


6
Зауважте, що при такому підході рядки "складаються знизу" подання у міру їх додавання. Це означає, що у коротких списках буде "порожнє" місце у верхній частині огляду, а не внизу.
Мейсон Лі

5

я використовую

setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);

щоб додати записи внизу, а старіші записи прокручуйте зверху, як стенограму чату


Зателефонуйте getListView().smoothScrollToPosition(getListAdapter.getCount() - 1);на початку, щоб прокрутити донизу на початку заняття.
palindrom

4

Найпростіше рішення:

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

3

Режим стенограми - це те, що ви хочете, і використовується Google Talk та програмою SMS / MMS. Ви правильно викликаєте notifyDatasetChanged () на своєму адаптері, коли ви додаєте елементи?


так я. список правильно оновлюється, але завжди починається зверху. Мені просто потрібно, щоб додати новий елемент і завжди прокручувати до кінця списку.
jramirez

Режим транскрипції фактично відключений програмою SMS. Не можу згадати, чому саме так.
Timmmm
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.