Glide列表问题

406 阅读1分钟

列表滑动

图片错乱问题

  • 通过设置Tag
 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());

  • Glide的解决方案
@Override
public Request getRequest() {
    Object tag = getTag();
    Request request = null;
    if (tag != null) {
        if (tag instanceof Request) {
            request = (Request) tag;
        } else {
            throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting");
        }
    }
    return request;
}

private void setTag(Object tag) {
    if (tagId == null) {
        isTagUsedAtLeastOnce = true;
        view.setTag(tag);
    } else {
        view.setTag(tagId, tag);
    }
}

private Object getTag() {
    if (tagId == null) {
        return view.getTag();
    } else {
        return view.getTag(tagId);
    }
}
public <Y extends Target<TranscodeType>> Y into(Y target) {
    Util.assertMainThread();
    if (target == null) {
        throw new IllegalArgumentException("You must pass in a non null Target");
    }
    if (!isModelSet) {
        throw new IllegalArgumentException("You must first set a model (try #load())");
    }

    //(1)把Request设置给View的tag。如果View有request就取消request。重新设置一个新的request。
    Request previous = target.getRequest();

    if (previous != null) {
        previous.clear();
        requestTracker.removeRequest(previous);
        previous.recycle();
    }

    Request request = buildRequest(target);
    target.setRequest(request);
    lifecycle.addListener(target);
    requestTracker.runRequest(request);

    return target;
}

把Request设置给View的tag。如果View有request就取消request。重新设置一个新的request。

图片请求是否支持取消

  • 第一种:自己通过调用viewTarget.clearOnDetach()
ImageView imageView = helper.itemView.findViewById(R.id.image);
ViewTarget viewTarget = new ViewTarget(imageView) {
    @Override
    public void onResourceReady(@NonNull Object resource, @Nullable Transition transition) {
              imageView.setImageDrawable((Drawable) resource);
    }
};
//(1)
viewTarget.clearOnDetach();
Glide.with(imageView.getContext()).load(item).into(viewTarget);
public final ViewTarget<T, Z> clearOnDetach() {
  if (attachStateListener != null) {
    return this;
  }
  attachStateListener =
      new OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(View v) {
          resumeMyRequest();
        }

        @Override
        public void onViewDetachedFromWindow(View v) {
          pauseMyRequest();
        }
      };
  maybeAddAttachStateListener();
  return this;
}
  • 第二种:监听滑动调用pauseRequests()resumeRequests()方法。
mRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        boolean sIsScrolling = false;
        if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) {
            sIsScrolling = true;
            Glide.with(GlideListActivity.this).pauseRequests();
        } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            if (sIsScrolling == true) {
                Glide.with(GlideListActivity.this).resumeRequests();

            }
            sIsScrolling = false;
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
    }
});