为什么要打造万能适配器?
在安卓开发中,用到ListView和GridView的地方实在是太多了,系统默认给我们提供的适配器(ArrayAdapter,SimpleAdapter)经常不能满足我们的需要,因此我们时常要去继承BaseAdapter类去实现一个自定义的适配器来满足我们的场景需要。
如果你是开发一个简单点的APP还好,可能ListView和GridView的数量不会太多,我们只要去写几个BaseAdapter实现类就可以了。
但如果有一天,你需要开发一个APP里面具有几十个ListView或者GridView的子页面,此时的你该怎么办?每个ListView或者GridView都去写一个适配的Adatper类吗?
当然你如果想做蛮牛不嫌累的话也不是不可以,但如果有办法可以让自己减少很多工作量,避免做重复无意义劳动,何乐而不为呢?
万能适配器思想?
软件设计模式:模板方法模式(有兴趣了解的朋友,可以参考看下我之前写过的博文《软件设计模式之模板方法模式(JAVA)》)
其实解决问题的核心思想很简单,一句话:抽取重复代码!
我们在继承BaseAdapter类时,都需要去实现它里面的抽象方法(getCount, getItem, getItemId, getView),其中除了getView这个方法里需要实现的代码不同,其他的都一样。
而这个getView方法里,我们考虑到性能的问题,我们经常会引入一个ViewHolder类(关于不清楚ViewHolder的朋友可以看看我之前写过的博文《安卓开发笔记——ListView加载性能优化ViewHolder》),尽可能的去节省资源。
那么解决问题的思路就出来了,我们可以把这个适配器抽取成2部分:
第一部分是解决(getCount, getItem, getItemId)方法里重复代码的问题。
第二部分是分离getView方法里使用到的ViewHolder,把它单独抽取出来成一个独立的类,利用键值对Key=>Value的方法,以控件ID去寻找对应的View对象。
如果你看完以上这些感觉已经云里来雾里去,没关系,接下去我们用代码说话。
传统适配器的实现方式:
1 package com.example.listviewtest; 2 3 import java.util.List; 4 5 import android.content.Context; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.BaseAdapter; 10 import android.widget.ImageView; 11 import android.widget.TextView; 12 13 /** 14 * 传统适配器Adapter写法 15 * 16 * @author Balla_兔子 17 * 18 */ 19 public class MyAdapter extends BaseAdapter { 20 private LayoutInflater layoutInflater; 21 private List<User> data; 22 23 public MyAdapter(Context context, List<User> data, int layoutId) { 24 //this.context = context; 25 this.layoutInflater = LayoutInflater.from(context); 26 this.data = data; 27 //this.layoutId = layoutId; 28 } 29 30 @Override 31 public int getCount() { 32 return data.size(); 33 } 34 35 @Override 36 public Object getItem(int position) { 37 return data.get(position); 38 } 39 40 @Override 41 public long getItemId(int position) { 42 return position; 43 } 44 45 @Override 46 public View getView(int position, View convertView, ViewGroup parent) { 47 ViewHolder viewHolder = null; 48 if (convertView == null) { 49 convertView = layoutInflater.inflate(R.layout.listview_item, parent, false); 50 viewHolder = new ViewHolder(); 51 viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image); 52 viewHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name); 53 viewHolder.tv_phone = (TextView) convertView.findViewById(R.id.tv_phone); 54 convertView.setTag(viewHolder); 55 } else { 56 viewHolder = (ViewHolder) convertView.getTag(); 57 } 58 59 User user = data.get(position); 60 viewHolder.iv_image.setImageResource(R.drawable.ic_launcher); 61 viewHolder.tv_name.setText(user.getName()); 62 viewHolder.tv_phone.setText(user.getPhone()); 63 64 return convertView; 65 } 66 67 private class ViewHolder { 68 ImageView iv_image; 69 TextView tv_name; 70 TextView tv_phone; 71 } 72 73 }