添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

使用recyclerView时遇到了图片错位的问题,这个问题网上已经讨论的很成熟,谨以此文章做个总结。

问题产生原因

根本原因: 因为有ViewHolder的重用机制,每一个item在移出屏幕后,都会被重新使用以节省资源,避免滑动卡顿。

问题现象: 就是每个item或者item数量多了以后,滑动太快时会出现图片错位。

一、设置占位图

Glide有两种方法设置占位图

1、直接在链式请求中加 .placeholder()

Glide.with(this)
        .load(picUrl)
        .placeholder(R.drawable.ic_loading)
        .into(holder.ivThumb)

2、添加监听,在回调方法中设置:

Glide.with(mContext)
     .load(picUrl)
     .error(R.drawable.ic_loading)
     .into(new SimpleTarget<GlideDrawable>() {
         @Override
         public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super  GlideDrawable> glideAnimation) {
                     holder.ivThumb.setImageDrawable(glideDrawable);
         @Override
         public void onStart() {
             super.onStart();
             holder.ivThumb.setImageResource(R.drawable.ic_loading);

二、设置TAG

使用setTag()方式。但是,Glide图片加载也是使用这个方法,所以需要使用setTag(key,value)方式进行设置,这种方式是不错的一种解决方式,注意取值的时候应该是getTag(key)这个方法,当异步请求回来的时候对比下tag是否一样,再判断是否显示图片,我使用的是position设置tag.

时间及事件梳理

 @Override
    public void onBindViewHolder(final VideoViewHolder holder, final int position) {
        holder.thumbView.setTag(R.id.tag_dynamic_list_thumb, position);
        Glide.with(mContext)
                .load(picUrl)
                .error(R.drawable.video_thumb_loading)
                .into(new SimpleTarget<GlideDrawable>() {
                    @Override
                    public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation {
                        if (position != (Integer) holder.thumbView.getTag(R.id.tag_dynamic_list_thumb))
                            return;
                            holder.thumbView.setImageDrawable(glideDrawable);
                    @Override
                    public void onStart() {
                        super.onStart();
                        holder.thumbView.setImageResource(R.drawable.ic_loading);

三、在onViewRecycled方法中重置item的ImageView并取消网络请求

流程:在onBindViewHolder中发起加载请求,然后在view被回收时取消网络请求

@Override
public void onBindViewHolder(VideoViewHolder holder, int position) {
    String istrurl = mImgList.get(position).getImageUrl();
    if (null == holder || null == istrurl || istrurl.equals("")) {
        return;
    Glide.with(mContext)
            .load(picUrl)
            .placeholder(R.drawable.ic_loading)
            .into(holder.thumbView);
@Override
public void onViewRecycled(VideoViewHolder holder) {
    if (holder != null) {
        Glide.clear(holder.thumbView);
        holder.thumbView.setImageResource(R.drawable.ic_loading);
    super.onViewRecycled(holder);
 

https://blog.csdn.net/u013183608/article/details/89296915

https://blog.csdn.net/u010126792/article/details/84374729

前言使用recyclerView时遇到了图片错位的问题,这个问题网上已经讨论的很成熟,谨以此文章做个总结。问题产生原因根本原因:因为有ViewHolder的重用机制,每一个item在移出屏幕后,都会被重新使用以节省资源,避免滑动卡顿。问题现象:就是每个item或者item数量多了以后,滑动太快时会出现图片错位。解决方案一、设置占位图Glide有两种方法设置占位图1...
RecyclerView用的是我们自定义的内部类ViewHolder来复用的,也就是复用的是ViewHoler 当屏幕下滑,item1滑出可视区域,将item1的ViewHolder对象给item8复用,那么此时item1ViewHolder对象持有的变量都是item1的。 item1ViewHolder对象,在onBindViewHolder(MyViewHolder holder, i...
使用recyclerView时遇到了图片错位的问题,这个问题网上已经讨论的很成熟,谨以此文章做个总结。 问题产生原因 根本原因: 因为有ViewHolder的重用机制,每一个item在移出屏幕后都会被重新使用以节省资源,避免滑动卡顿。 1.第一次进入页面,RecyclerView载入,不做任何触摸操作 2.Adapter经过onCreateViewHolder()创建当前显示给用户...
Glide内部已经使用了setTag的方式, 如果再使用ImageView的setTag会报错,所以使用setTag(xxx,xxx)函数。 try { String uri = item.getBackgroundUrl(); holder.mBackground.setTag(R.id.imageid,uri)...
很多人会问为什么要用 glide,其它的库可以么?其实只要图片库带有对应的方法都是可以的,只不过真心觉得这个库不错,就算是推荐吧。 然后着重讲 Recyclerview 是因为 Recyclerview 在 adapter 的 onBindViewHolder 对item的操作比较严格,如果处理操作比较多,耗时长(比如单个item的图片比较多)就会造成Recyclerview卡的现象(Li
之前一段时间使用使用Recyclerview做了一个图片加载的模块,使用GridLayoutManager来展示的,但是发现加载过程出现了一个问题,在该模块使用的是Glide(毕竟确实牛批啊,这框架)进行加载,然鹅,在加载网络图片的时候出现了一个尴尬的问题,图片错位了,纳闷翻了一篇博客: https://www.2cto.com/kf/201607/522038.html, 有兴趣的朋友...
瀑布流失效问题 RecycleView瀑布流用Glide加载网络图片会导致瀑布流失效,因为不知道网络加载图片具体高度是多少;这时候我们可以手动设置图片高度,随机值,这样瀑布流就能正常使用了 @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { ResultBeanData.ResultBean.HotInfoBean hotInfoBean = datas.get(.
刚开始以为是listview或者Recyclerview的缓存复用问题,结果研究了半天才知道是Glide圆形头像CircleImageView的问题。  直接贴代码,代码很简单,直接在Recyclerview的onBinderViewHolder里面或者Listview的getView里面把把设置头像的代码加上Tag。 String tag = (String) holder.contac...
1. 设置LayoutManager的缓存大小 在RecyclerView初始化时,你可以为其设置一个LayoutManager,并在LayoutManager设置缓存大小(即预加载View数量)。可以使用如下代码: ```java LinearLayoutManager layoutManager = new LinearLayoutManager(context); layoutManager.setInitialPrefetchItemCount(data.size()); // data是你的数据集合 recyclerView.setLayoutManager(layoutManager); 这样设置后,RecyclerView会在初始化时预加载所有的View。 2. 自定义RecyclerView.Adapter 如果LayoutManager的缓存大小不能满足你的需求,你可以自定义RecyclerView.Adapter来实现预加载所有的View。你可以在Adapter的构造函数将所有的View全部创建出来,并保存在一个List,这样在RecyclerView滑动时就可以直接从List取出View显示。 不过这种方式需要注意内存占用问题,如果Item数量过多,可能会导致内存溢出。因此在实现时需要结合具体情况来考虑。