ListView的优化原理
首先要优化ListView就得先了解ListView加载数据原理,这是前提。
ListVeiw列表的显示需要三个元素:
ListVeiw: 用来展示列表的View。
适配器 : 用来把数据映射到ListView上。
数据源:具体的将被映射的字符串,图片,或者基本组件。
系统要绘制ListView了,它首先用getCount()函数得到要绘制的这个列表的长度,然后开始绘制第一行,调用getView()函数。在这个函数里面首先获得一个View(这个看实际情况,如果是一个简单的显示则是View,如果是一个自定义的里面包含很多控件的时候它其实是一个ViewGroup),然后再实例化并设置各个组件及其数据内容并显示它。ListView的工作原理如下:ListView 针对每个item,要求 adapter “返回一个视图” (getView),也就是说ListView在开始绘制的时候,系统首先调用getCount()函数,根据它的返回值得到ListView的长度,然后根据这个长度,调用getView()一行一行的绘制ListView的每一项。如果你的getCount()返回值是0的话,列表一行都不会显示,如果返回1,就只显示一行。返回几则显示几行。如果我们有几千几万甚至更多的item要显示怎么办?为每个Item创建一个新的View?实际上Android早已经缓存了这些视图.
如果你有几千几万甚至更多的选项(item)时,其中只有可见的项目存在内存中,其他的在Recycler中 ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的。当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图。还有就是每个条目布局中都有很多控件,这些控件也可以重复使用,利用一个内部类来缓存这些控件,并把内部类和convertView绑定,在convertView不为空时就直接取出缓存对象来复用。
在ListView和Adapter的显示中,ListView是个容器,负责装载和呈现每个条目的布局。**Adapter**是负责将ListView的数据源逐个取出,再把数据和条目布局中的对应控件进行组合,形成具体的每个条目,供ListView去显示。
@Override
public View getView(int position,
View convertView, ViewGroup parent) {
Log.i("TAG", "convertView="+convertView);
View v=null;
ViewHolder vh=null;
if(convertView==null){
v=View.inflate(context,resource,null);
vh=new ViewHolder();
vh.iv=(ImageView) v.findViewById(R.id.imageView1);
vh.tv01=(TextView) v.findViewById(R.id.textView1);
vh.tv02=(TextView) v.findViewById(R.id.textView2);
v.setTag(vh);
}else{
v=convertView;
vh=(ViewHolder)v.getTag();
}
Contact c=data.get(position);
String name=c.getName();
String phone=c.getPhone();
int photo=c.getPhoto();
vh.iv.setImageResource(photo);
vh.tv01.setText(name);
vh.tv02.setText(phone);
return v;
}
class ViewHolder{
ImageView iv;
TextView tv01;
TextView tv02;
};