由于需求的原因,无法使用placeholder设置占位图,只能在监听到图片加载失败后,设置图片的背景等在做一些其他的操作。但是存在一个问题,即加载失败的url由于没有缓存,如果下次刷新还是加载失败的话,明明监听的是失败的回调逻辑,但是设置的默认背景图还是会闪一下。代码如下。
Glide.with(iv).load(url)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
// TODO: 2021/7/15 失败的逻辑
return true;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(iv);
所以就跟进去源码看了一下,glide做了什么操作。
//部分源码 返回了DrawableImageViewTarget
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 IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
//而DrawableImageViewTarget集成自ImageViewTarget ImageViewTarget 里面有一个onResourceReady方法
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
if (transition == null || !transition.transition(resource, this)) {
//内部也是调用了maybeUpdateAnimatable
setResourceInternal(resource);
} else {
//使用动画
maybeUpdateAnimatable(resource);
}
}
可以看到直接使用into加载的话,默认时使用DrawableImageViewTarget的,而DrawableImageViewTarget设置drawable的时候是有动画的,那么会不会和动画有关系呢?
所以我们就自定义ViewTarget,替换掉DrawableImageViewTarget。
如下:
static class ImageViewTarget extends CustomViewTarget<ImageView, Drawable> {
public ImageViewTarget(@NonNull ImageView ivPic) {
super(ivPic);
}
@Override
protected void onResourceCleared(@Nullable Drawable placeholder) {
// TODO: 2021/7/15 加载被取消逻辑处理
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
// TODO: 2021/7/15 失败的逻辑
}
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
//自行设置Drawable
this.view.setImageDrawable(resource);
}
}
直接在into的时候使用即可,如下:
Glide.with(iv).load(url).into(new ImageViewTarget(ivHead));
经测试,完美解决加载图片闪烁问题,且自定义viewTarget可完全自行根据逻辑处理加载的各种场景。完美!