Listview Gulir ke akhir daftar setelah memperbarui daftar

292

Saya ingin memastikan bahwa daftar tersebut digulir sampai ke bagian bawah, setelah saya memperbarui tampilan daftar dengan menggunakan listAdapter, sehingga ini menampilkan elemen terakhir yang dimasukkan dalam daftar. Bagaimana saya bisa melakukan ini?

Saya mencoba ini tetapi tidak berhasil:

lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

Terima kasih

ramirez
sumber
coba lakukan ini berfungsi ... messagesListView.setTranscriptMode (ListView.TRANSCRIPT_MODE_NORMAL); messagesListView.setStackFromBottom (true);
Superdev
lv.setTranscriptMode (ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL) hanya memastikan bahwa listView akan digulir ke bawah setelah memanggil adaptor.notifyDataSetChanged. Jika ini tidak berhasil, cobalah untuk mendefinisikan properti ini dalam xml seperti yang Anda lihat di posting di bawah ini.
tomm

Jawaban:

418

Andaikan Anda tahu kapan data daftar telah berubah, Anda dapat secara manual memberi tahu daftar untuk menggulir ke bawah dengan mengatur pemilihan daftar ke baris terakhir. Sesuatu seperti:

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);
        }
    });
}
Mason Lee
sumber
@ Bhupendra itu tidak perlu. Anda dapat melakukannya tanpa utas juga, seperti yang ditunjukkan dalam jawaban Warting.
sagarpatidar
2
@ Bhupendra setSelection () memperbarui UI. Dengan memanggil pos (Runnable) pada tampilan, Anda memastikan kode Runnable dijalankan pada utas Android UI. Secara umum melakukannya dengan cara ini kecuali Anda tahu Anda sudah berada di utas UI, atau memastikannya dengan beberapa cara lain.
Mason Lee
5
tampaknya juga bahwa menggunakan pos pada adaptor yang baru ditetapkan menyebabkan animasi gulir sambil memastikan berada di utas utama dan menggunakan setSelection segera setelah mengatur adaptor tidak menyebabkan animasi gulir
Gianluca P.
1
@ SaifHamed sebagaimana dikomentari oleh Mason Lee pada jawaban Kevin, ini juga menyebabkan daftar pendek memiliki ruang "kosong" di bagian atas tampilan daripada bagian bawah yang kemungkinan besar bukan perilaku yang dimaksudkan.
dashhund
16
Anda juga dapat menggunakan myListView.smoothScrollToPosition (myListAdapter.getCount () - 1); untuk pengguliran yang lancar
Zar E Ahmer
238

Anda perlu menggunakan parameter ini dalam tampilan daftar Anda:

  • Gulir lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

  • Atur kepala daftar ke bawah lv.setStackFromBottom(true);

Anda juga dapat mengatur parameter ini dalam XML, mis. seperti ini:

<ListView
   ...
   android:transcriptMode="alwaysScroll"
   android:stackFromBottom="true" />
dev.serghini
sumber
27
Perhatikan bahwa dengan pendekatan ini, baris "susun dari bawah" tampilan saat ditambahkan. Ini berarti bahwa daftar pendek akan memiliki ruang "kosong" di bagian atas tampilan, bukan bagian bawah, yang tidak selalu sesuai dengan yang diinginkan.
Mason Lee
2
Pertanyaan cepat: Bagaimana saya bisa membuat gulungan menjadi animasi? Penyebab saat ini ketika saya memberi tahuDataSetChanged () ia melompat tanpa animasi?!?
Georg
@ Georg Sudahkah Anda menonaktifkan animasi di Opsi Pengembang di perangkat Anda?
JonasCz
35

Kombinasi TRANSCRIPT_MODE_ALWAYS_SCROLL dan setSelection membuatnya berfungsi untuk saya

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);    
    }
});
Wärting
sumber
29

Saya sudah berhasil menggunakan ini sebagai respons terhadap klik tombol, jadi saya kira Anda juga dapat menggunakannya setelah memperbarui konten Anda:

myListView.smoothScrollToPosition(theListAdapter.getCount() -1);
Álex
sumber
1
Ini solusi hebat. Sederhana, satu baris.
Josh Larson
12

Untuk mendapatkan ini di ListFragment:

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

Menambahkan jawaban ini karena jika seseorang melakukan pencarian google untuk masalah yang sama dengan ListFragment ia hanya menemukan ini ..

Salam

Klatschen
sumber
9

Menggunakan: Atur kepala daftar ke bawah lv.setStackFromBottom(true);

Dikerjakan untuk saya dan daftar tersebut digulir ke bawah secara otomatis saat pertama kali ditampilkan. Daftar kemudian bergulir sebagaimana mestinya dengan TRANSCRIPT_MODE_ALWAYS_SCROLL.

Kevin Parker
sumber
6
Perhatikan bahwa dengan pendekatan ini, baris "susun dari bawah" tampilan saat ditambahkan. Ini berarti bahwa daftar pendek akan memiliki ruang "kosong" di bagian atas tampilan, bukan bagian bawah.
Mason Lee
5

saya menggunakan

setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);

untuk menambahkan entri di bagian bawah, dan entri lama gulir dari atas, seperti transkrip obrolan

Plugie
sumber
Hubungi getListView().smoothScrollToPosition(getListAdapter.getCount() - 1);onstart untuk menggulir ke bawah di awal aktivitas.
palindrom
4

Solusi paling sederhana adalah:

    listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
    listView.setStackFromBottom(true);
ucMedia
sumber
3

Mode transkrip adalah apa yang Anda inginkan dan digunakan oleh Google Talk dan aplikasi SMS / MMS. Apakah Anda memanggil notifyDatasetChanged () dengan benar pada adaptor Anda saat Anda menambahkan item?

Guy Romain
sumber
ya, benar. daftar diperbarui dengan benar, tetapi selalu dimulai dari atas. Saya hanya perlu untuk menambahkan item baru dan selalu gulir ke akhir daftar.
jramirez
Mode transkrip sebenarnya dinonaktifkan oleh aplikasi SMS. Saya tidak ingat persis mengapa.
Timmmm