最近做项目时遇到一个问题,当列表中有图片时,滑动会出现错乱,原因主要是ItemView的复用导致的,解决方法往往是将imageUrl设为imageView的Tag,然后在绑定视图时通过比较imageView.getTag()和当前的imageUrl是否一致来判断是否需要重新加载图片。
以前使用UIL库是通过设置ImageLoadingListener在onLoadingComplete中进行比较,但现在使用的Glide库,这个库的加载比较简单,直接通过into(imageView)就将图片设置进去了,后来研究了一下,发现into里面可以不直接传imageView,而是传一个Target,里面同样有加载完成等回调。
这里总结了一个设置列表里面图片的方法,可以支持gif和非gif图片,在加载失败时显示指定的图片,还可以根据需要设置是否调整ImageView的尺寸大小以适应图片大小,以及可以设置ImageView的最大宽度。具体实现如下:
/**
* 加载列表里面的图片,解决复用时图片错乱的问题
*
* @param context
* @param imageView
* @param url
* @param defaultImageId
* @param adjustSize 是否需要调整ImageView的尺寸适应图片大小
* @param maxImageWidth 最大的ImageView的宽度,只有在adjustSize为true时才有效
*/
public static void setListImage(Context context, final ImageView imageView, final String url, final int defaultImageId, final boolean adjustSize, final int maxImageWidth) {
boolean isGif = url.endsWith(".gif");
if (isGif) {
Glide.with(context).load(url).asGif().diskCacheStrategy(DiskCacheStrategy.SOURCE).error(defaultImageId).into(new SimpleTarget<GifDrawable>() {
@Override
public void onResourceReady(GifDrawable resource, GlideAnimation<? super GifDrawable> glideAnimation) {
if (resource == null || TextUtils.equals(url, (String) imageView.getTag())) {
return;
}
imageView.setTag(url);
if (adjustSize) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.width = Math.min(resource.getIntrinsicWidth(), maxImageWidth);
params.height = params.width * resource.getIntrinsicHeight() / resource.getIntrinsicWidth();
}
imageView.setImageDrawable(resource);
resource.start();
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
if (errorDrawable == null) {
return;
}
imageView.setTag(null);
if (adjustSize) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.width = Math.min(errorDrawable.getIntrinsicWidth(), maxImageWidth);
params.height = params.width * errorDrawable.getIntrinsicHeight() / errorDrawable.getIntrinsicWidth();
}
imageView.setImageDrawable(errorDrawable);
}
});
} else {
Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.SOURCE).error(defaultImageId).into(new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
if (resource == null || TextUtils.equals(url, (String) imageView.getTag())) {
return;
}
imageView.setTag(url);
if (adjustSize) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.width = Math.min(resource.getIntrinsicWidth(), maxImageWidth);
params.height = params.width * resource.getIntrinsicHeight() / resource.getIntrinsicWidth();
}
imageView.setImageDrawable(resource);
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
if (errorDrawable == null) {
return;
}
imageView.setTag(null);
if (adjustSize) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.width = Math.min(errorDrawable.getIntrinsicWidth(), maxImageWidth);
params.height = params.width * errorDrawable.getIntrinsicHeight() / errorDrawable.getIntrinsicWidth();
}
imageView.setImageDrawable(errorDrawable);
}
});
}
}