我想在350ms之后加载我recyclerview
中的图像,我想我使用了错误的方法。这是我的代码:
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.songView.setText(objects_.get(position).getAlbum());
holder.artistView.setText(objects_.get(position).getArtist());
holder.cover.setImageDrawable(context.getResources().getDrawable(R.drawable.song));
if(holder.r!=null){
handler.removeCallbacks(holder.r);
}
holder.r = new Runnable() {
@Override
public void run() {
Drawable img = Drawable.createFromPath(objects_.get(position).getCover());
if (img != null) {
holder.cover.setImageDrawable(img);
Bitmap bitmap = ((BitmapDrawable) img).getBitmap();
Palette palette = Palette.from(bitmap).generate();
Palette.Swatch p = palette.getVibrantSwatch();
if (p != null) {
holder.albumholder.setBackgroundColor(p.getRgb());
}
}
}
};
handler.postDelayed(holder.r,300);
}
但我对此有疑问。当我快速滚动recyclerview
先前项目的图像时,首先加载到新项目图片。您可以通过此链接查看GIF中的结果:
http://8pic.ir/images/nkaaeqdvigqy4c6g2h5n.gif
我该怎么做才能解决它?
答案 0 :(得分:3)
我不明白为什么你需要这350ms的延迟,但如果你想这样做尝试其他方法:
您的问题与RecyclerView回收(惊奇......)项目视图而不是创建新项目有关。这意味着您将看到之前加载的图像,如果您已发布延迟任务(handler.postDelayed(...)
),则会在视图被回收时执行事件,因此可以为特定列表项加载错误的图像。
一般问题是你在onBindViewHolder上做了很多工作。你应该尝试在这里减少计算,或者至少尝试将它们移动到一个单独的线程(处理程序使用它创建的同一个线程 - 在这种情况下是UI线程)。
holder.handler.removeCallbacksAndMessages(null);
handler.postDelayed(...)
)也有可能你需要的只是像Picasso这样漂亮的图像加载库。
答案 1 :(得分:1)
我们知道回收站视图在滚动期间重复使用相同的视图,因此当您延迟加载一段时间时它会显示较旧的图像,之后它会更新您的图像视图。
解决方案只是在lazyload之前将您的imageview重置为默认值(即白色背景或默认图像)状态。
你应该避免使用setimageresource(),而应该使用setimagedrawable()
答案 2 :(得分:0)
使用AsyncTask代替使用runnable加载图像。您需要为每个图像执行单独的AsyncTask。此AsyncTask将作为WeakReference保存在drawable对象中,该对象将在相应的ImageView中设置。
WeakReferences用于映射目的。使用WeakReferences的优点是,只要应用程序不需要,就可以从内存中删除条目。它们将被垃圾收集器删除。我们需要使用WeakReferences,因为可能会同时执行大量AsyncTasks(等于RecyclerView中存在的项目数),Android系统或您的应用程序将无法识别哪个AsyncTask属于哪个没有这些参考的ImageView。
现在,由于在ImageView中设置了drawable,它将包含对其各自的AsyncTask的WeakReference。这个AsyncTask将处理在ImageView上设置的相应位图或drawable,所有这些都将在UI线程之外完成。
为了在drawable对象中设置AsyncTask,你需要创建一个自定义可绘制类,它将作为Drawable对象使用,但是可以将AsyncTask附加到它上面。
这个Drawable对象和AsyncTask将负责加载图像。
Android开发者网站上提供了此概念的完整说明和代码。请访问以下链接:http://developer.android.com/training/displaying-bitmaps/process-bitmap.html