RecyclerView圖片錯亂複用問題
由於開發排行榜過程中遇到些問題,這裏統一做下記錄,由於RecyclerView的緩存複用機制,所以會導致item的複用問題,當圖片時尤爲明顯,例如用戶列表中有頭像的沒頭像的,這時明顯能看到錯亂問題。
直接說下2種方案,包括正確的不正確的,好的壞的:
1、直接每次都給圖片設置setImageDrawable(),然後加載網絡圖片
這樣的話,每次刷新的時候圖片都會先被設置成setImageDrawable() 中的圖片,然後加載完網絡圖片的時候纔會顯示出來。猛的一看沒問題,但是這就會造成什麼呢,當你刷新的時候列表圖片會有一個閃動的過程,也就是: 網絡圖片->設置的圖片->網絡圖片這麼一個閃動過程。體驗不好,我們需要實現當圖片地址不變的時候圖片也依舊顯示不變就好了。
2、給每個item中的圖片設置tag
這個是目前的比較靠譜的方案了吧,給圖片設置tag(下文中的tag設置爲了圖片的url),當該圖片沒有tag的時候說明這裏還沒有開始複用,那麼直接加載網絡圖片即可;當該圖片有tag的時候並且tag和圖片的url相同,說明是複用來的並且圖片的url還是對的,那麼這個圖片直接加載即可;當圖片的tag和圖片url不同時,說明這個圖片是複用來的,所以就需要把原來的圖片先設置爲你的佔位符,然後加載網絡圖片。
以上就是整個邏輯了,僞代碼如下:
if (TUtils.isEmpty(item.getHeadUrl())) {
holder.mImgAvatar.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_placeholder_avatar));
} else {
String avatarTag = (String) holder.mImgAvatar.getTag();//如果tag爲null則說明是全新的視圖,否則是複用來的視圖
//如果有圖片的TAG有並且和之前設置的一樣,那麼直接再次加載即可
if (null == avatarTag || avatarTag.equals(item.getHeadUrl())) {
Glide.with(holder.mImgAvatar)
.load(item.getHeadUrl())
.override(SizeUtils.dp2px(34))
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
holder.mImgAvatar.setImageDrawable(resource);
}
});
}
//如果和原來的tag不同,也就是url不同,那麼就先清空原來的圖片,然後加載新的圖片
else {
holder.mImgAvatar.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_placeholder_avatar));
Glide.with(holder.mImgAvatar)
.load(item.getHeadUrl())
.override(SizeUtils.dp2px(34))
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
holder.mImgAvatar.setImageDrawable(resource);
}
});
}
}
holder.mImgAvatar.setTag(item.getHeadUrl());