Мерцание изображения при прокрутке в RecyclerView
я пытаюсь отобразить список песен, найденных на устройстве, запрашивающем данные непосредственно из MediaStore. Я использую RecyclerView
и адаптер, который использует CursorAdapter
для получения данных из MediaStore.
Когда адаптер onBindViewHolder
вызывается, запрос передается в
3 ответов
я решил, добавив поле в ViewHolder
содержащий AsyncTask
относительно этого элемента. В bindView
функция I fisrt установить AsyncTask.cancel(true)
и, внутри задачи я сделал чек isCancelled()
перед применением полученного изображения с помощью Picasso.with(...).load(...)
. Это само решена мерцание.
компании bindview
if(holder.downloadImageTask != null)
holder.downloadImageTask.cancel(true);
holder.downloadImageTask = (DownloadImageTask) new DownloadImageTask(mediaStoreHelper, context, holder.imgArt).execute(holder.album_id);
AsyncTask
private class DownloadImageTask extends AsyncTask<String, String, String> {
private MediaStoreHelper mediaStoreHelper;
private ImageView imageView;
private Context context;
public DownloadImageTask(MediaStoreHelper mediaStoreHelper, Context context, ImageView imageView)
{
this.mediaStoreHelper = mediaStoreHelper;
this.context = context;
this.imageView = imageView;
}
@Override
protected String doInBackground(String... ids) {
return mediaStoreHelper.getAlbumArtPath(ids[0]);
}
protected void onPostExecute(String result) {
if(!isCancelled())
Picasso.with(context)
.load(new File(result))
.placeholder(R.drawable.ic_music)
.fit()
.into(imageView);
}
}
для полноты, это также удалить изображение из переработанных элементов и установить заполнитель.
@Override
public void onViewRecycled(SongViewHolder holder) {
super.onViewRecycled(holder);
Picasso.with(holder.itemView.getContext())
.cancelRequest(holder.imgArt);
Picasso.with(holder.itemView.getContext())
.load(R.drawable.ic_music)
.fit()
.into(holder.imgArt);
}
это решение заставило меня думать, что проблема времени intercurring внутри AsyncTask
между извлечением изображения из MediaStore и временем, когда изображение фактически применяется в ImageView
от Пикассо.
комментировать эти строки
мерцание происходит, потому что bind не вызывает только один раз для одного элемента, поэтому он вызывает снова и снова для одной строки, и вы устанавливаете null каждый раз, а также устанавливаете представление на нем. производя мерцание.
Picasso.with(holder.imgArt.getContext())
.cancelRequest(holder.imgArt);
holder.imgArt.setImageDrawable(null);
асинхронный задач используется совершенно неправильно.
во-первых, вы никогда не должны выполнять анонимный асинхронных задач.
во-вторых, избавьтесь от этой асинхронной задачи в адаптере, потому что это, похоже, вызывает проблему.
получить данные для адаптера, а затем показать его.
кстати, завершение Пикассо лучше сделать так:
@Override public void onViewRecycled(VH holder) {
super.onViewRecycled(holder);
Picasso.with(holder.itemView.getContext())
.cancelRequest(holder.getImageView());
}