解决ListView 缓存机制带来的显示不正常问题

ListView加载数据原理:系统绘制ListView时,首先会用getCount()函数得到要绘制的这个列表的长度,然后开始逐行绘制。然后调用getView()函数,在这个函数里面首先获得一个View(简单item,如字符串或者单个组件的显示则是View,自定义的item,包含很多控件的时候是一个ViewGroup),然后再实例化并设置各个组件及其数据内容并显示它。如果我们有大量的item要显示怎么办?不可能为每个Item创建一个新的View,这会消耗大量的内存,可能会OOM!解决办法就是缓存View然后重复利用。这个图是解释了系统缓存的过程,当有前面的Item已经划出屏幕时,它的View将被后面的Item复用。http://img1.51cto.com/attachment/201206/102950574.jpg

显示不正常问题:缓存机制固然很好,但在使用时要特别注意。比如,前面的Item里面的组件的数据也会被带到将要复用的Item中,从而导致显示错误。

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		Holder holder = null;
		convertView = null; //禁用缓存机制
		if (convertView == null) {
			convertView = mInflater.inflate(R.layout.bus_unit, parent, false);
			holder = new Holder();

			holder.station = (TextView) convertView
					.findViewById(R.id.textView_station);



解决办法:最简单的方法就是禁用它的缓存机制,这只适用于Item比较少的情况。

对于Item比较多的情况,这样的解决办法显然是不合适的。另外一种解决办法其实也挺简单的,只要将Item中的组件数据再初始化为原来的状态就行了。

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		Holder holder = null;
		if (convertView == null) {
			convertView = mInflater.inflate(R.layout.bus_unit, parent, false);
			holder = new Holder();

			holder.station = (TextView) convertView
					.findViewById(R.id.textView_station);
			holder.stationState = (ImageView) convertView
					.findViewById(R.id.imageView_station_state);
			convertView.setTag(holder);
		} else {
			holder = (Holder) convertView.getTag();
		}
		//应对缓存机制,初始化数据。
		holder.stationState.setImageResource(R.drawable.presence_offline);
		holder.station.setText(bean.getBusList().get(position));
		
		if (bean.getBusList().get(position).equals(bean.getCurrentPosition())) {
			String text = bean.isDirection() ? "当前位置" : "目标位置";
			holder.stationState.setImageResource(R.drawable.presence_now);
		}
		
			String station;
			int index2 = bean.getBusList().get(position).indexOf("(");
			if (index2 != -1) {
				station = bean.getBusList().get(position).substring(0, index2);
			} else {
				station = bean.getBusList().get(position);
			}
			if (bean.getStationList().contains(station)) {
				if (bean.getStateList().get(index).equals("前往")) {
				holder.stationState.setImageResource(R.drawable.presence_online);
			}
		}
		return convertView;
	}

	


版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/AndyDai/p/4734099.html