listview中涉及两种设计模式:adapte模式和observer模式。
如下是两种模式的UML类图:
先来分析adapter模式:
listview冲的那个client角色,接口Adapter充当target,BaseAdapter充当adapter,而listview的数据对象就是adaptee。
Adapter接口抽象出listview需要的接口getItem,getCount,getView。
BaseAdapter子类中实现的Adapter接口,其实是对数据对象的操作,也就是对adaptee依赖关系。
以SimpleAdapter类为例分析:
public class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpinnerAdapter {
private List<? extends Map<String, ?>> mData;
public int getCount() {
return mData.size();
}
/**
* @see android.widget.Adapter#getItem(int)
*/
public Object getItem(int position) {
return mData.get(position);
}
/**
* @see android.widget.Adapter#getItemId(int)
*/
public long getItemId(int position) {
return position;
}
/**
* @see android.widget.Adapter#getView(int, View, ViewGroup)
*/
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(mInflater, position, convertView, parent, mResource);
}
private View createViewFromResource(LayoutInflater inflater, int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = inflater.inflate(resource, parent, false);
} else {
v = convertView;
}
bindView(position, v);
return v;
}
}
成员变量mData是uml类图中的adaptee,listview对数据对象的访问抽象出的接口在Adapter、接口中。
public interface Adapter {
int getCount();
Object getItem(int position);
long getItemId(int position);
View getView(int position, View convertView, ViewGroup parent);
int getItemViewType(int position);
int getViewTypeCount();
}
listview对data的使用抽象成几个接口函数,这是关键的一步。通过抽象出的接口,实现了listview不需要关心data的类型,就可以用统一的方式得到需要的数据。对于不同的data类型,我们只需要根据具体的data类型,实现对应的adapter即可。
如果不使用adapter模式,data数据和对data数据的访问都要移到listview中的话,会使得listview代码非常复杂。而且针对不同的data,用户还要修改listview,这是开发中非常terrible的事情。而且data相关的操作不属于listview的功能范畴,也应该移到listview类外面完成,应该让listview尽可能的功能单一。通过对Adapter接口的抽象,不同的data类型,用户只需要是相对应的接口即可,这样使用listview 就非常简单了。