glide利用ViewTarget解决加载ImageView闪烁的问题

glide利用ViewTarget解决加载ImageView闪烁的问题

由于需求的原因,无法使用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可完全自行根据逻辑处理加载的各种场景。完美!

你可能感兴趣的:(android,my,java,android,glide)