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

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,这个方法可以解决问题,但是我觉得

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

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

     

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

		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

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

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
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);
				}
			}
		}

这样就解决了这个问题,本人测试使用没有问题,记录下来仅供以后查看,写的不好多多包含。


  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值