前言
使用recyclerView时遇到了图片错位的问题,这个问题网上已经讨论的很成熟,谨以此文章做个总结。
问题产生原因
根本原因: 因为有ViewHolder的重用机制,每一个item在移出屏幕后,都会被重新使用以节省资源,避免滑动卡顿。
问题现象:就是每个item或者item数量多了以后,滑动太快时会出现图片错位。
解决方案
一、设置占位图
Glide有两种方法设置占位图
1、直接在链式请求中加.placeholder()
:
Glide.with(this)
.load(picUrl)
.placeholder(R.drawable.ic_loading)
.into(holder.ivThumb)
2、添加监听,在回调方法中设置:
Glide.with(mContext)
.load(picUrl)
.error(R.drawable.ic_loading)
.into(new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation) {
holder.ivThumb.setImageDrawable(glideDrawable);
}
@Override
public void onStart() {
super.onStart();
holder.ivThumb.setImageResource(R.drawable.ic_loading);
}
});
二、设置TAG
使用setTag()方式。但是,Glide图片加载也是使用这个方法,所以需要使用setTag(key,value)方式进行设置,这种方式是不错的一种解决方式,注意取值的时候应该是getTag(key)这个方法,当异步请求回来的时候对比下tag是否一样,再判断是否显示图片,我使用的是position设置tag.
时间及事件梳理
代码
@Override
public void onBindViewHolder(final VideoViewHolder holder, final int position) {
holder.thumbView.setTag(R.id.tag_dynamic_list_thumb, position);
Glide.with(mContext)
.load(picUrl)
.error(R.drawable.video_thumb_loading)
.into(new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation {
if (position != (Integer) holder.thumbView.getTag(R.id.tag_dynamic_list_thumb))
return;
holder.thumbView.setImageDrawable(glideDrawable);
}
@Override
public void onStart() {
super.onStart();
holder.thumbView.setImageResource(R.drawable.ic_loading);
}
});
}
三、在onViewRecycled方法中重置item的ImageView并取消网络请求
流程:在onBindViewHolder中发起加载请求,然后在view被回收时取消网络请求
@Override
public void onBindViewHolder(VideoViewHolder holder, int position) {
String istrurl = mImgList.get(position).getImageUrl();
if (null == holder || null == istrurl || istrurl.equals("")) {
return;
}
Glide.with(mContext)
.load(picUrl)
.placeholder(R.drawable.ic_loading)
.into(holder.thumbView);
}
@Override
public void onViewRecycled(VideoViewHolder holder) {
if (holder != null) {
Glide.clear(holder.thumbView);
holder.thumbView.setImageResource(R.drawable.ic_loading);
}
super.onViewRecycled(holder);
}