来自mediastore

时间:2016-04-13 04:17:46

标签: java android

我想在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

我该怎么做才能解决它?

3 个答案:

答案 0 :(得分:3)

我不明白为什么你需要这350ms的延迟,但如果你想这样做尝试其他方法:

您的问题与RecyclerView回收(惊奇......)项目视图而不是创建新项目有关。这意味着您将看到之前加载的图像,如果您已发布延迟任务(handler.postDelayed(...)),则会在视图被回收时执行事件,因此可以为特定列表项加载错误的图像。

一般问题是你在onBindViewHolder上做了很多工作。你应该尝试在这里减少计算,或者至少尝试将它们移动到一个单独的线程(处理程序使用它创建的同一个线程 - 在这种情况下是UI线程)。

  1. 在视图持有者内部而不是在适配器内部创建处理程序。
  2. 将一些占位符设置为图像
  3. 清除当前等待执行的任务(消息):
  4. holder.handler.removeCallbacksAndMessages(null);

    1. 后期加载任务(handler.postDelayed(...)
    2. 也有可能你需要的只是像Picasso这样漂亮的图像加载库。

答案 1 :(得分:1)

我们知道回收站视图在滚动期间重复使用相同的视图,因此当您延迟加载一段时间时它会显示较旧的图像,之后它会更新您的图像视图。

解决方案只是在lazyload之前将您的imageview重置为默认值(即白色背景或默认图像)状态。

你应该避免使用setimageresource(),而应该使用setimagedrawable()

setImageResource Vs setDrawable

答案 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