1.ViewHolder类中代码 主要三个方法加上构造方法
主要三个方法:get(),getView(),getConvertView();
public class ViewHolder {2.CommonAdapter 抽象类类中的代码
SparseArray<View> mView;//这是一种<以int做键,object做值>的更高效的Map
int mPosition;
View mConvertView;
public ViewHolder(Context context, int position, ViewGroup parent, int layoutId){
this.mPosition=position;
this.mView=new SparseArray<>();
mConvertView=LayoutInflater.from(context).inflate(layoutId,null);
mConvertView.setTag(this);
}
public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId,int position){
if (convertView==null){
return new ViewHolder(context,position,parent,layoutId);
}else {
ViewHolder holder= (ViewHolder) convertView.getTag();
holder.mPosition=position;
return holder;
}
}
public <T extends View> T getView(int viewId){
View view=mView.get(viewId);
if (view==null){
view=mConvertView.findViewById(viewId);
mView.put(viewId,view);
}
return (T)view;
}
public View getConvertView(){
return mConvertView;
}
//辅助:将convert方法继续简化,可以为常用的textView,imageView 等添加同类方法
public ViewHolder setText(int viewId,String text){
TextView tv=getView(viewId);
tv.setText(text);
return this;
}
//使用getPosition结合List<Integer>可以配合点击事件保存选中Item项
public int getPosition() {
return mPosition;
}
}
重点解析:通过提供抽象convert()方法分解出getView()方法中的不易复用的代码功能
public abstract class CommonAdapter<T> extends BaseAdapter{3.不考虑ListView点击事件等后续情况可以在Activity中使用匿名内部类的方式创建适配器对象,代码如下:
Context context;
List<T> mDatas;
int mlayoutId;
public CommonAdapter(List<T> mDatas, Context context,int layoutId) {
this.mDatas = mDatas;
this.context = context;
this.mlayoutId=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.get(context,convertView,parent,mlayoutId, position);
convert(viewHolder,this.getItem(position));
return viewHolder.getConvertView();
}
public abstract void convert(ViewHolder holder,T t);
}
list.setAdapter(new CommonAdapter<Bean>(beanList,this,R.layout.list_item) {4.考虑的ListView的点击事件等等情况,不适合用匿名内部类的时候就用外部类,也很方便:@Override
public void convert(ViewHolder viewHolder, final Bean bean) {
viewHolder.setText(R.id.id_title,bean.getTitle())
.setText(R.id.id_desc,bean.getDesc())
.setText(R.id.id_time,bean.getTime())
.setText(R.id.id_phone,bean.getPhone());//使用链式编程简化代码
//配合CheckBox使用,解决convertView复用后CheckBox的选中问题//这种写法实在bean中有isChecked属性来保存CheckBox的选中状态的请况下
final CheckBox cb=viewHolder.getView(R.id.id_check);
cb.setChecked(bean.getChecked());
cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bean.setChecked(cb.isChecked());
}
});
}
});
public class YouAdapter extends CommonAdapter<Bean>{
List<Integer> mPos=new ArrayList<>();//定义一个集合来保存选中项
public YouAdapter( List<Bean> mDatas,Context context,int layoutId) {
super(mDatas,context,layoutId);
}
//现在YouAdapter里只有一个方法,建议使用匿名内部类的写法简化
@Override
public void convert(final ViewHolder viewHolder, final Bean bean) {
((TextView)viewHolder.getView(R.id.id_title)).setText(bean.getTitle());
((TextView)viewHolder.getView(R.id.id_desc)).setText(bean.getDesc());
((TextView)viewHolder.getView(R.id.id_time)).setText(bean.getTime());
((TextView)viewHolder.getView(R.id.id_phone)).setText(bean.getPhone());
final CheckBox cb=viewHolder.getView(R.id.id_check);
// cb.setChecked(bean.getChecked());
//
// cb.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// bean.setChecked(cb.isChecked());
// }
// });
//或者在bean中没有isCheck的属性来保存是否选中,可以定义一个List<Integer>集合来保存所选中Item
cb.setChecked(false);
if (mPos.contains(viewHolder.getPosition())){
cb.setChecked(true);
}
cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cb.isChecked()) {
mPos.add(viewHolder.getPosition());
}else{
mPos.remove((Integer) viewHolder.getPosition());
}
}
});
}
}