之前一段時間使用使用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) { 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) { if (holder != null) { Glide.clear(holder.mImvShow); } super.onViewRecycled(holder); }ok啦,問題這麼解決啦。
+++++++++++++++++++++++++++++++++++++++
如果大佬們有比較好的解決方式,歡迎交流,文章若有誤導的地方,歡迎斧正。