关于GridView加载和滑动时造成的图片混乱问题总结

    xiaoxiao2025-07-06  17

    [html]  view plain  copy if(!viewMap.containsKey(position) || viewMap.get(position) == null){               holder = new Holder();               convertView = LayoutInflater.from(mContext).inflate(R.layout.host_grid_item, null);               holder.imageview = (ImageView) convertView.findViewById(R.id.wallpaper_host_image);               convertView.setTag(holder);               viewMap.put(position, convertView);           }else{               convertView = viewMap.get(position);               holder = (Holder) convertView.getTag();           }           最近项目遇到一个BUG,是应用GridView加载图片,会出现图片重复加载的情况,还有滑动的时候下面的图片也会重复。

            跟代码会发现getView方法中position=0时会重复加载很多次,并且当position=0时convertView对象会有不同,在网上搜索了一下原因,

    总结起来就是如果GridView的宽度高度不确定,getView会多执行几次position=0来计算item的高度和宽度,得出每屏幕能够显示最大的item,

    同时也给出了两个解决方案:一是将GridView设置固定宽高或者设置为宽高属性设置为match_parent,这个方法可以解决问题,但是我觉得

    不具备通用性;二是下面的方法

    [html]  view plain  copy if(parent.getChildCount() == position){               //正常的position,执行代码           }else{               //无效的可以忽略           }   经过笔者测试初始化的时候是会没有问题,但是滚动后数据就会出现问题,所以这个也不能解决问题。

          

          经过笔者总结可以使用另一种方法:笔者或者我们通常为了提高getView效率会向如下这么写

    [html]  view plain  copy if (convertView == null) {       holder = new Holder();       convertView = LayoutInflater.from(mContext).inflate(R.layout.host_grid_item, null);       holder.imageview = (ImageView) convertView.findViewById(R.id.wallpaper_host_image);       convertView.setTag(holder);   }else {       holder = (Holder) convertView.getTag();   }  

            这就导致了有些convertView会被不同的position使用,导致图片会重复加载,下面提供一个解决方案:

    先定义一个Map

    [html]  view plain  copy private HashMap<Integer, View> viewMap;   然后使用下面的方法存储convertView,使其和position一一对应,保证不会出现不同position使用同一convertView对象

    [html]  view plain  copy if(!viewMap.containsKey(position) || viewMap.get(position) == null){               holder = new Holder();               convertView = LayoutInflater.from(mContext).inflate(R.layout.host_grid_item, null);               holder.imageview = (ImageView) convertView.findViewById(R.id.wallpaper_host_image);               convertView.setTag(holder);               viewMap.put(position, convertView);           }else{               convertView = viewMap.get(position);               holder = (Holder) convertView.getTag();           }   然后为了保证Map不会因为存储过多而溢出,在加上一个清理屏幕范围外的view [html]  view plain  copy if(viewMap.size() > 20){               synchronized (convertView) {                   for(int i = 1;i < mGridview.getFirstVisiblePosition() - 3;i ++){                       viewMap.remove(i);                   }                   for(int i = mGridview.getLastVisiblePosition() + 3;i < getCount();i ++){                       viewMap.remove(i);                   }               }           }  

    附一张截图

    转载请注明原文地址: https://ju.6miu.com/read-1300427.html
    最新回复(0)