之前一段时间使用使用Recyclerview做了一个图片加载的模块,使用GridLayoutManager来展示的,但是发现加载过程中出现了一个问题,在该模块中使用的是Glide(毕竟确实牛批啊,这框架)进行加载,然鹅,在加载网络图片的时候出现了一个尴尬的问题,图片错位了,纳闷中翻了一篇博客:
https://www.2cto.com/kf/201607/522038.html,
有兴趣的朋友可以看看,之后经过日志打印,数据是正常的,解析也是没有问题,那么基本是确认是控件复用导致的。
那么产生这个问题是怎么回事呢?
是这样的:执行onbindviewholder()方法------>Glide开始异步请求数据------>页面滑动,控件被重用------->异步加载请求回来了,显示在之前复用的控件上。
于是乎就产生了图片错乱。
经过阅读其他大佬博客,看到有这么几种解决方式,感觉里面有些细节是需要纠正的:
1,使用占位图,诚然加载一个异步请求这是需要的,Glide提供了一个placeholder供用户们加载占位图。
Glide.with(this)
.load(iStrImgUrl)
.placeholder(R.drawable.ic_launcher_background)
.into(mImvShow);
但是这种占位图的方式并不能解决今天博客中提到的问题,仅仅是在执行加载请求预置一张图片,请求一回来,还是会被覆盖
2.使用settag()方式,这种方式还是比较好的,但是,需要注意的是,Glide图片加载也是使用将这个方法的,所以当你在Bindviewholder()使用时会直接抛异常,你需要使用settag(key,value)方式进行设置,这种方式是不错的一种解决方式,注意取值的时候应该是gettag(key)这个方法哈,当异步请求回来的时候对比下tag是否一样在判断是否显示图片。这边直接复制博主的代码了。
//给ImageView打上Tag作为特有标记
imageView.setTag(tag);
//下载图片
loadImage();
//根据tag判断是不是需要设置给ImageView
if(tag == iamgeView.getTag()) {
imageView.setBitmapImage(iamge);
}
3.也就是我使用的一种解决方式,原理就是holer开始被复用的时候,那么直接中断请求
在holder中发起加载请求。
@Override
public void onBindViewHolder(Myholder holder, int position) {//这个方法是Adapter里面的
String istrurl = mImgList.get(position).getImageUrl();
if (null == holder || null == istrurl || istrurl.equals("")) {
return;
}
Glide.with(mContext)
.load(istrurl)
.placeholder(R.drawable.ic_launcher_background)
.into(holder.mImvShow);
}
在view被回收的时候那么直接请求请求
@Override
public void onViewRecycled(Myholder holder)//这个方法是Adapter里面的
{
if (holder != null)
{
Glide.clear(holder.mImvShow);
}
super.onViewRecycled(holder);
}
ok啦,问题这么解决啦。
+++++++++++++++++++++++++++++++++++++++
如果大佬们有比较好的解决方式,欢迎交流,文章若有误导的地方,欢迎斧正。