一.BaseAdapter的基本概念
对于Android程序员来说,BaseAdapter肯定不会陌生,灵活而优雅是BaseAdapter最大的特点。开发者可以通过构造BaseAdapter并搭载到ListView或者GridView这类多控件布局上面,实现软件所需要的布局效果。同时,BaseAdapter也是适配器里面最基础的一个类,其他的例如SimpleAdapter、ArrayAdapter都是直接或者间接继承BaseAdapter,所以说学好BaseAdapter基本就熟练掌握了适配器的使用了。
二 .BaseAdapter的优化
针对BaseAdapter的优化主要有两点:复用convertView 以及使用ViewHolder重用组件,不用每次都findViewById,我们具体通过代码来体会吧!
2.1、复用ConvertView
我们先来看一段代码,如下所示:
1 @Override 2 public View getView(int position, View convertView, ViewGroup parent) { 3 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false); 4 ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon); 5 TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName); 6 TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); 7 8 img_icon.setBackgroundResource(mData.get(position).getaIcon()); 9 txt_aName.setText(mData.get(position).getaName()); 10 txt_aSpeak.setText(mData.get(position).getaSpeak()); 11 return convertView; 12 }
这段代码在使用ListView或者GridView的时候经常看到,界面上有多少个Item,那么getView方法就会被调用多少次,而每调用一次getView方法都要通过inflate()方法加载一次item的布局xml文件,其实这个convertView是系统提供给我们的可供复用的View 的缓存对象,那就做一下判断咯,修改下,优化后的代码:
1 @Override 2 public View getView(int position, View convertView, ViewGroup parent) { 3 4 if(convertView == null){ 5 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false); 6 } 7 8 ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon); 9 TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName); 10 TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); 11 12 img_icon.setBackgroundResource(mData.get(position).getaIcon()); 13 txt_aName.setText(mData.get(position).getaName()); 14 txt_aSpeak.setText(mData.get(position).getaSpeak()); 15 return convertView; 16 }
红色的代码部分就是针对convertView的使用优化,如果convertView为空,那么就表示是第一次加载布局,那么就通过inflate()方法加载item的布局xml文件,如果不为空,那么就不在重新加载,而是直接拿来使用了。
2.2、使用ViewHolder重用组件
在上面的代码中,我们在getView()方法内部多次调用了findViewById方法获取item布局里面的控件,也就是说,getView方法被调用多少次,那么findViewById就会调用多少次,但一般情况下,我们的ListView或者GridView的Item 一般都是一样的布局,我们可以对这里在优化下,我们可以自己定义一个ViewHolder类来对这一部分 进行性能优化!修改后的代码如下:
1 @Override 2 public View getView(int position, View convertView, ViewGroup parent) { 3 ViewHolder holder = null; 4 if(convertView == null){ 5 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false); 6 holder = new ViewHolder(); 7 holder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon); 8 holder.txt_aName = (TextView) convertView.findViewById(R.id.txt_aName); 9 holder.txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); 10 convertView.setTag(holder); //将Holder存储到convertView中 11 }else{ 12 holder = (ViewHolder) convertView.getTag(); 13 } 14 holder.img_icon.setBackgroundResource(mData.get(position).getaIcon()); 15 holder.txt_aName.setText(mData.get(position).getaName()); 16 holder.txt_aSpeak.setText(mData.get(position).getaSpeak()); 17 return convertView; 18 } 19 20 static class ViewHolder{ 21 ImageView img_icon; 22 TextView txt_aName; 23 TextView txt_aSpeak; 24 }
我们的优化手段是使用一个ViewHolder来缓存Item布局里面的控件,以后编写BaseAdapter照着这个模板写就对了,另外这个修饰ViewHolder的 static,关于是否定义成静态,跟里面的对象数目是没有关系的,加静态是为了在多个地方使用这个 Holder的时候,类只需加载一次,如果只是使用了一次,加不加也没所谓!
关于BaseAdapter优化内容就这么多了。如果还有更好的优化策略,欢迎广大园友指导!