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


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

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

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

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

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


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.


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


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

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?


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.