通用的Adapter
(一)传统的写法
package com.example.generaladapter;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapterO extends BaseAdapter {
private LayoutInflater mInflater;
private List<Bean> mDatas;
public MyAdapterO(Context context,List<Bean> datas){
mInflater=LayoutInflater.from(context);
mDatas=datas;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mDatas.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub]
Bean bean=(Bean) getItem(position);
ViewHolder viewHolder=null;
if(convertView==null){
convertView=mInflater.inflate(R.layout.item_listview, null);
viewHolder=new ViewHolder();
viewHolder.mTitle=(TextView) convertView.findViewById(R.id.id_title);
viewHolder.mDesc=(TextView) convertView.findViewById(R.id.id_content);
viewHolder.mTime=(TextView) convertView.findViewById(R.id.id_time);
viewHolder.mPhone=(TextView) convertView.findViewById(R.id.id_phone);
convertView.setTag(viewHolder);
}else{
viewHolder=(ViewHolder) convertView.getTag();
}
viewHolder.mTitle.setText(bean.getTitle());
viewHolder.mDesc.setText(bean.getContent());
viewHolder.mTime.setText(bean.getTime());
viewHolder.mPhone.setText(bean.getPhone());
return convertView;
}
private class ViewHolder{
TextView mTitle;
TextView mDesc;
TextView mTime;
TextView mPhone;
}
}
传统的写法中,对应每一种列表项布局,写一个ViewHolder.由于项目中有多种列表项,要写的代码非常多。能不能有简化的方法呢?
下面我们来看看有什么办法来简化代码的编写
(二)ViewHolder的优化分析
在ViewHolder 中编写getView方法,方法原型如下:
View getViewById(int resId);通过 传入的Id获得相应的View组件。
public View getView(int position,View convertView,ViewGroup parent)
{
ViewHolder holder=...//初始化viewHolder对象
TextView tv=holder.getViewById(viewId); //调用getView方法获得view对象。
tv.setText(..);
}
实现getViewById()方法的数据结构是SparseArray,他存储<\int ,object>键值对,效率高于map.int对应资源id,Object对应View组件。
(三)初始化
ViewHolder的初始化方法,public ViewHolder()中,应该实现如下的功能:
ViewHolder viewHolder=null;
if(convertView==null){
convertView=mInflater.inflate(R.layout.item_listview, null);
viewHolder=new ViewHolder();
viewHolder.mTitle=(TextView) convertView.findViewById(R.id.id_title);
viewHolder.mDesc=(TextView) convertView.findViewById(R.id.id_content);
viewHolder.mTime=(TextView) convertView.findViewById(R.id.id_time);
viewHolder.mPhone=(TextView) convertView.findViewById(R.id.id_phone);
convertView.setTag(viewHolder);
}else{
viewHolder=(ViewHolder) convertView.getTag();
}
convertView==null时,创建新的ViewHolder,并初始化他。 ,convertView!=null时,viewHolder=convertView.getTag();
代码修改如下:
public ViewHolder(Context context, ViewGroup parent, int layout,
int position) {
// TODO Auto-generated constructor stub
mPosition = position;
mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layout, parent,false);
mConvertView.setTag(this);
}
public static ViewHolder get(Context context, View convertView,
ViewGroup parent, int layout, int position) {
if (convertView == null) {
return new ViewHolder(context, parent, layout, position);
} else {
ViewHolder holder = (ViewHolder)convertView.getTag();
holder.mPosition=position;
return holder;
}
}
public View getConvertView(){
return mConvertView;
}
(四)getViewById()方法,根据viewId返回view
public <T extends View>T getView(int viewId){
View view=mViews.get(viewId);
if(view==null)
{
view=mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T)view;
}
(五)viewHolder 和BaseAdapter结合
在Adapter的getView()方法中,获得ViewHolder的方法可以缩短为一行
ViewHolder holder=ViewHolder.get(this.mContext, convertView, parent, R.layout.item_listview, position);
获取TextView控件并赋值,可以写成
((TextView)holder.getView(R.id.id_title)).setText(bean.getTitle());
返回convertView
return holder.getConvertView();
这种写法节约了多少代码呢?假设有10个listView,按照传统的写法,要定义10个ViewHolder类,并且,在getView方法中if(convertView==null),就要对viewHolder中的每一个组件使用findViewById(),初始化。