往往在项目中我会回遇到很多不同样式布局的listview/gridview的item布局或不同的实体类ban。假如我们有10个不同的实体类,10个不同的item布局,那我们是不是要去写10个adapter适配器,这样显然是重复的做了很多无用功。其实我们可以把其中公共的部分提出来。在activity中只需要传一个bean,布局文件和上下文即可。那么实现代码看下面:
package com.example.commonadaptertest.utils;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;
/**
*
* 通用的ListView的BaseAdapter,所有的ListView的自定义adapter都可以继承这个类哦
*/
public abstract class ListViewAdapter<T> extends BaseAdapter {
//为了让子类访问,于是将属性设置为protected
protected Context mContext;
protected List<T> mDatas;
protected LayoutInflater mInflater;
private int layoutId; //不同的ListView的item布局肯能不同,所以要把布局单独提取出来
public ListViewAdapter(Context context, List<T> datas, int layoutId) {
this.mContext = context;
mInflater = LayoutInflater.from(context);
this.mDatas = datas;
this.layoutId = layoutId;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public T getItem(int position) {
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//初始化ViewHolder,使用通用的ViewHolder,一样代码就搞定ViewHolder的初始化咯
ViewHolder holder = ViewHolder.get(mContext, convertView, parent, layoutId, position);//layoutId就是单个item的布局
convert(holder, getItem(position),position);
return holder.getConvertView();
}
//将convert方法公布出去
public abstract void convert(ViewHolder holder, T t,int position);
}
package com.example.commonadaptertest.utils;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ViewHolder {
private SparseArray<View> mViews;
private int mPosition;
private View mConvertView;
public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
this.mPosition = position;
this.mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
mConvertView.setTag(this);
}
public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
if (convertView == null) {
return new ViewHolder(context, parent, layoutId, position);
} else {
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.mPosition = position; //即时ViewHolder是复用的,但是position记得更新一下
return holder;
}
}
/*
通过viewId获取控件
*/
//使用的是泛型T,返回的是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;
}
public View getConvertView() {
return mConvertView;
}
}
上面2个就是核心代码块。里面注释很清楚了。
package com.example.commonadaptertest;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import com.example.commonadaptertest.entity.Bean;
import com.example.commonadaptertest.utils.ListViewAdapter;
import com.example.commonadaptertest.utils.ViewHolder;
public class ListViewAdapterWithViewHolder extends ListViewAdapter<Bean> {
//MyAdapter需要一个Context,通过Context获得Layout.inflater,然后通过inflater加载item的布局
public ListViewAdapterWithViewHolder(Context context, List<Bean> datas,int layoutId) {
super(context, datas, layoutId);
}
@Override
public void convert(ViewHolder holder, final Bean bean,final int position) {
((TextView) holder.getView(R.id.titleTv)).setText(bean.getTitle());
((TextView) holder.getView(R.id.descTv)).setText(bean.getDesc());
((TextView) holder.getView(R.id.timeTv)).setText(bean.getTime());
((TextView) holder.getView(R.id.phoneTv)).setText(bean.getPhone());
((TextView) holder.getView(R.id.phoneTv)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(mContext, "position:"+position+"内容:"+bean.getPhone(), Toast.LENGTH_SHORT).show();
}
});
}
}
上面代码块就是设值写逻辑的地方,当然里面的点击事件也可以进一步优化。这个就你们自己去提取吧,这里不多说了。然后就是在activity中的调用,如下:
listViewAdapterWithViewHolder = new ListViewAdapterWithViewHolder(this, mDatas,R.layout.item_listview);
listView.setAdapter(listViewAdapterWithViewHolder);
大功告成了!!!