对于 Android 程序员来说,BaseAdapter 肯定不会陌生,灵活而优雅是 BaseAdapter 最大的特点。开发者可以通过构造 BaseAdapter 并搭载到 ListView 或者 GridView 这类多控件布局上面,实现软件所需要的布局效果。同时,BaseAdapter 也是适配器里面最基础的一个类,其他的例如 SimpleAdapter、ArrayAdapter 都是直接或者间接继承 BaseAdapter,所以说学好 BaseAdapter 基本就熟练掌握了适配器的使用了。
针对 BaseAdapter 的优化主要有两点:复用 convertView 以及使用 ViewHolder 重用组件,不用每次都 findViewById,我们具体通过代码来体会吧!
我们先来看一段代码,如下所示:
- 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 文件,如果不为空,那么就不在重新加载,而是直接拿来使用了。
在上面的代码中,我们在 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 优化内容就这么多了。如果还有更好的优化策略,欢迎广大园友指导!
来源: http://www.cnblogs.com/nylcy/p/6516712.html