自定义Listview适配器的优化

自定义Listview适配器的优化

【以下两段只是我自己的理解,要是表达不清,可跳过看后面的】

介绍:Listview控件一直是我们在android项目开发中经常需要用到的。对于刚接触listview的我,在写listview时候都用的自己自定义的listview,这样可以随意的控制我们的listview item。创建过程一般是先写个item类用来管理每个item的组件值,然后就是写一个xml页面,设计listview item每个组件的摆放位置,接着就是自定义一个类继承BaseAdapter,创建一个构造方法,重写下他的4个方法,并在getview()方法去设置每个item的值。最后在调用listview.setAdapter()方法。这样一个自定义ListView就写好了。


优化:按以上方法确实ListView就创建好了,并能正常运行程序,但是大家有没有想过我们自定义适配器中重写的getview()方法在我们程序运行的时候到底要运行多少次,毕竟我们手机屏幕有限,不可能把所有的listview条目都显示出来,那么是不是表示我们每次加载新的item都要调用呢,答案是肯定的,每次新加载出一个新的item都要调用一次getview()方法。而我们注意到,每次执行getview()方法,那么就会重复调用findViewById()方法,后面就不用说了,这是需要优化的地方之一。第二其实是也是getView()方法的一个参数convertView,细心的人会发现其实convertView就是我们需要加载的这个item,可是我们知道listview中每个item的布局都是一样的,所以这里的convertView也是一样的,那么我们能不能在只需要加载一个convertView,然后后面item都用这个convertView,这里我先给出答案,是可以的,但是不是加载一个,是加载一个屏幕所能容纳的item个数,能不能想明白,话说我也有点晕,不过想想应该就是这样的。


优化点:(专业术语)

1:重用了convertView,很大程度上的减少了内存的消耗

解决方法:先判断convertView是否为空,若为空则先获取再调用,否则可直接调用。

2:上面的写法会有一个缺点,就是每次在getVIew的时候,都需要重新的findViewById,重新找到控件,然后进行控件的赋值以及事件相应设置。

解决方法:通常有一个内部类class ViewHolder,这个ViewHolder,用来标识view中一些控件,方便进行一些事件相应操作的设置
       设置ViewHolder为static,也就是静态的,静态类只会在第一次加载时会耗费比较长时间,但是后面就可以很好帮助加载,同时保证了内存中只有一个ViewHolder,节省了内存的开销
       View中的setTag(Onbject)表示给View添加一个格外的数据,以后可以用getTag()将这个数据取出来。 

代码参考:
public class GeneralAdapter extends BaseAdapter {
	private List<Data>mDatas;
	private LayoutInflater mInflater;
	private Context mContext;
	public GeneralAdapter(List<Data> mDatas, Context mContext) {
		super();
		this.mDatas = mDatas;
		this.mContext = mContext;
		this.mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return mDatas.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return mDatas.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		View view;
		MyHolder myHolder;
		Data data;
		if(convertView==null){
			view = mInflater.inflate(R.layout.listview_common_item, parent,false);
			myHolder = new MyHolder();
			myHolder.imageView = (ImageView)view.findViewById(R.id.iv);
			myHolder.textView = (TextView)view.findViewById(R.id.tv);
			view.setTag(myHolder);
		}else{
			view = convertView;
		}
		data = mDatas.get(position);
		myHolder = (MyHolder) view.getTag();
		myHolder.imageView.setImageResource(data.getId());
		myHolder.textView.setText(data.getContent());
		return view;
	}
	static class MyHolder{
		ImageView imageView;
		TextView textView;
	}
}


猜你喜欢

转载自blog.csdn.net/const_qiu/article/details/51472641