前言
使用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);
}