Saya memiliki RecyclerView yang memuat beberapa data dari API, termasuk url gambar dan beberapa data, dan saya menggunakan networkImageView untuk memuat gambar secara malas.
@Override
public void onResponse(List<Item> response) {
mItems.clear();
for (Item item : response) {
mItems.add(item);
}
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
Berikut implementasi untuk Adaptor:
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
if (isHeader(position)) {
return;
}
// - get element from your dataset at this position
// - replace the contents of the view with that element
MyViewHolder holder = (MyViewHolder) viewHolder;
final Item item = mItems.get(position - 1); // Subtract 1 for header
holder.title.setText(item.getTitle());
holder.image.setImageUrl(item.getImg_url(), VolleyClient.getInstance(mCtx).getImageLoader());
holder.image.setErrorImageResId(android.R.drawable.ic_dialog_alert);
holder.origin.setText(item.getOrigin());
}
Masalahnya adalah ketika kita menyegarkan di recyclerView, itu berkedip untuk beberapa saat di awal yang terlihat aneh.
Saya hanya menggunakan GridView / ListView dan berfungsi seperti yang saya harapkan. Tidak ada blincking.
konfigurasi untuk RecycleView di onViewCreated of my Fragment
:
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mGridLayoutManager = (GridLayoutManager) mRecyclerView.getLayoutManager();
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return mAdapter.isHeader(position) ? mGridLayoutManager.getSpanCount() : 1;
}
});
mRecyclerView.setAdapter(mAdapter);
Adakah yang menghadapi masalah seperti itu? apa alasannya?
Jawaban:
Coba gunakan ID stabil di RecyclerView.Adapter Anda
setHasStableIds(true)
dan timpagetItemId(int position)
.Tanpa ID yang stabil, setelah itu
notifyDataSetChanged()
, ViewHolders biasanya ditetapkan ke posisi yang tidak sama. Itulah alasan mengapa saya berkedip.Anda dapat menemukan penjelasan yang bagus di sini.
sumber
Menurut halaman terbitan ini .... ini adalah animasi perubahan item tampilan daur ulang default ... Anda dapat mematikannya .. coba ini
Ubah di versi terbaru
Dikutip dari blog pengembang Android :
sumber
Ini hanya bekerja:
sumber
code
ItemAnimator animator = recyclerView.getItemAnimator (); if (animator instanceof SimpleItemAnimator) {((SimpleItemAnimator) animator) .setSupportsChangeAnimations (false); }code
Saya memiliki masalah yang sama saat memuat gambar dari beberapa url dan kemudian imageView berkedip. Diselesaikan dengan menggunakan
dari pada
yang menghindari untuk memuat ulang data lama yang tidak berubah.
sumber
coba ini untuk menonaktifkan animasi default
ini cara baru untuk menonaktifkan animasi sejak dukungan android 23
cara lama ini akan berfungsi untuk versi lama pustaka dukungan
sumber
Dengan asumsi
mItems
adalah koleksi yang mendukung AndaAdapter
, mengapa Anda menghapus semuanya dan menambahkan kembali? Anda pada dasarnya mengatakan bahwa semuanya telah berubah, jadi RecyclerView me-rebinds semua tampilan daripada yang saya asumsikan perpustakaan Gambar tidak menanganinya dengan benar di mana ia masih mengatur ulang Tampilan meskipun itu adalah url gambar yang sama. Mungkin mereka memiliki beberapa solusi untuk AdapterView sehingga berfungsi dengan baik di GridView.Alih-alih memanggil
notifyDataSetChanged
yang akan menyebabkan pengikatan ulang semua tampilan, panggil peristiwa pemberitahuan terperinci (beri tahu ditambahkan / dihapus / dipindahkan / diperbarui) sehingga RecyclerView hanya akan mengembalikan tampilan yang diperlukan dan tidak ada yang akan berkedip.sumber
Recyclerview menggunakan DefaultItemAnimator sebagai animator defaultnya. Seperti yang Anda lihat dari kode di bawah ini, mereka mengubah alfa pemegang tampilan saat perubahan item:
Saya ingin mempertahankan sisa animasi tetapi menghapus "flicker" jadi saya mengkloning DefaultItemAnimator dan menghapus 3 baris alfa di atas.
Untuk menggunakan animator baru, cukup panggil setItemAnimator () di RecyclerView Anda:
sumber
Di Kotlin, Anda dapat menggunakan 'ekstensi kelas' untuk RecyclerView:
sumber
Hai @Ali mungkin ulangan terlambat. Saya juga menghadapi masalah ini dan menyelesaikannya dengan solusi di bawah ini, ini dapat membantu Anda, silakan periksa.
Kelas LruBitmapCache.java dibuat untuk mendapatkan ukuran cache gambar
VolleyClient.java singleton class [extends Application] ditambahkan di bawah kode
di konstruktor kelas tunggal VolleyClient tambahkan potongan di bawah ini untuk menginisialisasi ImageLoader
Saya membuat metode getLruBitmapCache () untuk mengembalikan LruBitmapCache
Semoga ini bisa membantu Anda.
sumber
bagi saya
recyclerView.setHasFixedSize(true);
bekerjasumber
Dalam kasus saya, tidak ada jawaban di atas maupun jawaban dari pertanyaan stackoverflow lain yang memiliki masalah yang sama.
Ya, saya menggunakan animasi khusus setiap kali item diklik, yang saya panggil notifyItemChanged (int position, Object Payload) untuk meneruskan payload ke kelas CustomAnimator saya.
Perhatikan, ada 2 metode onBindViewHolder (...) yang tersedia di Adaptor RecyclerView. Metode onBindViewHolder (...) yang memiliki 3 parameter akan selalu dipanggil sebelum metode onBindViewHolder (...) yang memiliki 2 parameter.
Umumnya, kami selalu mengganti metode onBindViewHolder (...) yang memiliki 2 parameter dan akar utama masalahnya adalah saya melakukan hal yang sama, karena setiap kali notifyItemChanged (...) dipanggil, metode onBindViewHolder (...) kami akan disebut, di mana saya memuat gambar saya di ImageView menggunakan Picasso, dan inilah alasannya memuat lagi terlepas dari dari memori atau dari internet. Sampai dimuat, itu menunjukkan kepada saya gambar placeholder, yang menjadi alasan berkedip selama 1 detik setiap kali saya mengklik itemview.
Kemudian, saya juga mengganti metode onBindViewHolder (...) lain yang memiliki 3 parameter. Di sini saya memeriksa apakah daftar payload kosong, lalu saya mengembalikan implementasi kelas super dari metode ini, jika tidak ada payload, saya hanya mengatur nilai alpha dari itemView pemegang ke 1.
Dan yay saya mendapatkan solusi untuk masalah saya setelah menghabiskan satu hari penuh dengan sedih!
Berikut kode saya untuk metode onBindViewHolder (...):
onBindViewHolder (...) dengan 2 parameter:
onBindViewHolder (...) dengan 3 parameter:
Berikut kode metode yang saya panggil onClickListener dari itemView viewHolder di onCreateViewHolder (...):
Catatan: Anda bisa mendapatkan posisi ini dengan memanggil metode getAdapterPosition () viewHolder Anda dari onCreateViewHolder (...).
Saya juga mengganti metode getItemId (int position) sebagai berikut:
dan menelepon
setHasStableIds(true);
objek adaptor saya dalam aktivitas.Semoga ini bisa membantu jika tidak ada jawaban di atas yang berhasil!
sumber
Dalam kasus saya, ada masalah yang jauh lebih sederhana, tetapi dapat terlihat / terasa sangat mirip dengan masalah di atas. Saya telah mengubah ExpandableListView menjadi RecylerView dengan Groupie (menggunakan fitur ExpandableGroup Groupie). Tata letak awal saya memiliki bagian seperti ini:
Dengan layout_height disetel ke "wrap_content", animasi dari grup yang diperluas ke grup yang diciutkan terasa seperti itu akan berkedip, tetapi itu sebenarnya hanya menganimasikan dari posisi "salah" (bahkan setelah mencoba sebagian besar rekomendasi di utas ini).
Bagaimanapun, cukup mengubah layout_height menjadi match_parent seperti ini memperbaiki masalah.
sumber
Saya memiliki masalah serupa dan ini berhasil untuk saya. Anda dapat memanggil metode ini untuk mengatur ukuran cache gambar
sumber
untuk aplikasi saya, saya mengalami beberapa perubahan data tetapi saya tidak ingin seluruh tampilan berkedip.
Saya menyelesaikannya dengan hanya memudarkan tampilan lama menjadi 0,5 alpha dan memulai alpha tampilan baru pada 0,5. Ini menciptakan transisi pemudaran yang lebih lembut tanpa membuat tampilan menghilang sepenuhnya.
Sayangnya karena implementasi pribadi, saya tidak dapat membuat subkelas DefaultItemAnimator untuk melakukan perubahan ini, jadi saya harus mengkloning kode dan membuat perubahan berikut
di animateChange:
di animateChangeImpl:
sumber
Menggunakan metode recyclerview yang tepat untuk memperbarui tampilan akan menyelesaikan masalah ini
Pertama, lakukan perubahan dalam daftar
Kemudian beri tahu menggunakan
Semoga ini bisa membantu !!
sumber
Coba gunakan stableId dalam tampilan pendaur ulang. Artikel berikut menjelaskannya secara singkat
https://medium.com/@hanru.yeh/recyclerviews-views-are-blinking-when-notifydatasetchanged-c7b76d5149a2
sumber
Solusi Kotlin:
sumber