文章目录
前言
最近在项目中使用RecyclerView+Glide发现了一些bug,在此记录一下。
一. RecyclerView中使用Glide出现加载图片闪烁
1.1 发现问题

如上图所示,在使用RecyclerView+Glide的时候会出现,图片多次叠加的问题。首先看下代码:
// 用了BaseQuickAdapter
@Override
protected void convert(BaseViewHolder holder, Bean bean) {
// loading加载
final View loading = holder.getView(R.id.loading);
loading.setVisibility(View.VISIBLE);
// 省略业务代码...
Glide.with(getContext())
.load(url) // 加载数据的URL
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) // 图片使用原始尺寸
.into(new SimpleTarget<Drawable>() {
// SimpleTarget已经过时
@Override
public void onResourceReady(@NonNull Drawable resource,
@Nullable Transition<? super Drawable> transition)
{
// 图片加载完成就隐藏loading
loading.setVisibility(View.GONE);
imageView.setImageDrawable(resource);
}
});
}
由于业务上要求需要显示loading,目前所做的是将loading的View置于ImageView下面,如果图片加载完成,那么就需要将loading给隐藏。
经过分析,之所以会上面图片所示的问题,主要还是由于RecyclerView的复用机制导致的。当我快速滑动到顶部的时候,顶部的那些View是复用被移出列表的itemView,但是这些被复用的itemView可能还在加载之前的数据,同时这些itemView还要加载当前位置上需要加载的数据,这就导致加载的时候会先出现被复用之前需要加载的数据,然后再加载复用之后需要加载的数据。
如果将上面的SimpleTarget改为直接into(imageView),就不会出现该问题!那么为什么会出现这种情况呢?
1.2 查看源码
首先看一下Glide在直接into的时候做了啥?
Glide源码:
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
// 省略代码...
// 主要看buildImageViewTarget
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
继续跟进:
buildImageViewTarget方法
@NonNull
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
跟进到buildTarget里面
ImageViewTargetFactory类
@NonNull
@SuppressWarnings("unchecked")
public <Z> ViewTarget<ImageView, Z> buildTarget(
@NonNull ImageView view, @NonNull Class<Z> clazz) {
if (Bitmap.class.equals(clazz)) {
return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
} else {
throw new

文章详细分析了在RecyclerView中使用Glide加载图片时出现闪烁的原因,主要是由于RecyclerView的复用机制和SimpleTarget的使用。通过查看Glide源码,解释了直接使用into(imageView)避免问题的原因,并提供了修改代码的示例,推荐使用Listener来管理加载状态。此外,还介绍了Glide4.0后推荐使用的CustomTarget和CustomViewTarget,以及它们的onLoadCleared和onResourceLoading方法的重要性。
最低0.47元/天 解锁文章
6401

被折叠的 条评论
为什么被折叠?



