Saya memiliki ListView
yang menampilkan item berita. Mereka mengandung gambar, judul dan beberapa teks. Gambar dimuat dalam utas terpisah (dengan antrian dan semua) dan ketika gambar diunduh, saya sekarang memanggil notifyDataSetChanged()
daftar adaptor untuk memperbarui gambar. Ini berfungsi, tetapi getView()
dipanggil terlalu sering, karena notifyDataSetChanged()
panggilan getView()
untuk semua item yang terlihat. Saya ingin memperbarui hanya satu item dalam daftar. Bagaimana saya melakukan ini?
Masalah yang saya miliki dengan pendekatan saya saat ini adalah:
- Menggulir lambat
- Saya memiliki animasi fade-in pada gambar yang terjadi setiap kali satu gambar baru dalam daftar dimuat.
Pertanyaan ini telah diajukan di Google I / O 2010, Anda dapat melihatnya di sini:
Dunia ListView, waktu 52:30
Pada dasarnya apa yang Romain Guy menjelaskan adalah untuk memanggil
getChildAt(int)
padaListView
untuk mendapatkan pandangan dan (saya pikir) callgetFirstVisiblePosition()
untuk mengetahui hubungan antara posisi dan indeks.Romain juga menunjuk ke proyek yang disebut Shelves sebagai contoh, saya pikir dia mungkin bermaksud metode
ShelvesActivity.updateBookCovers()
, tetapi saya tidak dapat menemukan panggilangetFirstVisiblePosition()
.PEMBARUAN LUAR BIASA DATANG:
RecyclerView akan memperbaikinya dalam waktu dekat. Seperti yang ditunjukkan pada http://www.grokkingandroid.com/first-glance-androids-recyclerview/ , Anda akan dapat memanggil metode untuk menentukan perubahan dengan tepat, seperti:
Juga, semua orang akan ingin menggunakan tampilan baru berdasarkan RecyclerView karena mereka akan dihargai dengan animasi yang terlihat bagus! Masa depan terlihat luar biasa! :-)
sumber
Beginilah cara saya melakukannya:
Item Anda (baris) harus memiliki id unik sehingga Anda dapat memperbaruinya nanti. Atur tag setiap tampilan saat daftar mendapatkan tampilan dari adaptor. (Anda juga dapat menggunakan tag kunci jika tag default digunakan di tempat lain)
Untuk pembaruan, periksa setiap elemen daftar, jika ada tampilan dengan id yang diberikan, itu terlihat sehingga kami melakukan pembaruan.
Ini sebenarnya lebih mudah daripada metode lain dan lebih baik ketika Anda berurusan dengan id bukan posisi! Anda juga harus menghubungi pembaruan untuk item yang terlihat.
sumber
dapatkan kelas model sebagai global seperti objek kelas model ini
dan inisialisasi ke global
dapatkan baris tampilan saat ini oleh model dengan menginisialisasi untuk model global
atur nilai yang diubah ke metode objek model global yang akan ditetapkan dan tambahkan notifyDataSetChanged kerjanya untuk saya
Berikut ini adalah pertanyaan terkait dengan jawaban yang bagus.
sumber
Jawabannya jelas dan benar, saya akan menambahkan ide untuk
CursorAdapter
kasus di sini.Jika Anda subklasifikasi
CursorAdapter
(atauResourceCursorAdapter
, atauSimpleCursorAdapter
), maka Anda bisa menerapkanViewBinder
atau menimpabindView()
dannewView()
metode, ini tidak menerima indeks item daftar saat ini dalam argumen. Karena itu, ketika beberapa data tiba dan Anda ingin memperbarui item daftar yang terlihat relevan, bagaimana Anda tahu indeksnya?Solusi saya adalah:
newView()
notifyDatasetChanged()
dan menyegarkan semuanyaKarena melihat daur ulang, jumlah referensi tampilan yang harus saya simpan dan iterate akan kira-kira sama dengan jumlah item daftar yang terlihat di layar.
sumber
Untuk RecycleView silakan gunakan kode ini
sumber
Saya menggunakan kode yang menyediakan Erik, bekerja dengan baik, tetapi saya memiliki adaptor khusus yang kompleks untuk tampilan daftar saya dan saya dihadapkan dengan dua kali implementasi kode yang memperbarui UI. Saya telah mencoba untuk mendapatkan tampilan baru dari metode getView adapter saya (daftar array yang menyimpan data listview semuanya telah diperbarui / diubah):
Ini bekerja dengan baik, tetapi saya tidak tahu apakah ini praktik yang baik. Jadi saya tidak perlu mengimplementasikan kode yang memperbarui daftar item dua kali.
sumber
tepatnya saya menggunakan ini
sumber
Saya membuat solusi lain, seperti metode RecyclyerView void
notifyItemChanged(int position)
, membuat kelas CustomBaseAdapter seperti ini:Jangan lupa untuk membuat kelas CustomDataSetObservable juga untuk
mDataSetObservable
variabel di CustomAdapterClass , seperti ini:di kelas CustomBaseAdapter ada metode
notifyItemChanged(int position)
, dan Anda dapat memanggil metode itu ketika Anda ingin memperbarui baris di mana pun Anda inginkan (dari klik tombol atau di mana pun Anda ingin memanggil metode itu). Dan voila !, baris tunggal Anda akan diperbarui secara instan ..sumber
Solusi saya: Jika benar *, perbarui data dan item yang dapat dilihat tanpa menggambar ulang seluruh daftar. NotifyDataSetChanged lain.
Benar - ukuran oldData == ukuran data baru, dan ID data lama beserta pesanannya == ID data baru dan pesanan
Bagaimana:
dan tentu saja:
Abaikan param terakhir ke bindView (saya menggunakannya untuk menentukan apakah saya perlu mendaur ulang bitmap untuk ImageDrawable).
Seperti yang disebutkan di atas, jumlah total tampilan 'terlihat' kira-kira jumlah yang sesuai pada layar (mengabaikan perubahan orientasi dll), jadi tidak ada masalah besar dalam hal memori.
sumber
Selain solusi ini ( https://stackoverflow.com/a/3727813/5218712 ) hanya ingin menambahkan bahwa itu harus berfungsi hanya jika
listView.getChildCount() == yourDataList.size();
Mungkin ada tampilan tambahan di dalam ListView.Contoh bagaimana elemen anak diisi:
sumber