1,单布局模式:
package com.shenbin.lvgvbaseadapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装BaseAdapter
* 单布局适配器
* Created by shenbin on 2015/12/25.
*/
public abstract class LvGvBaseAdapter<T> extends BaseAdapter {
private List<T> datas = new ArrayList<T>(); //显示的数据
private int resId; //item布局文件的id(R.layout.item_lv)
private Context context; //上下文对象
public LvGvBaseAdapter(Context context,int resId) {
this.resId = resId;
this.context = context;
}
/**
* 几个传入数据的方法
* @param datas
*/
public void setDatas(List<T> datas) {
this.datas.clear();
addDatas(datas);
this.notifyDataSetChanged();
}
public void addDatas(List<T> datas) {
this.datas.addAll(datas);
this.notifyDataSetChanged();
}
public void addOneData(T data) {
this.datas.add(data);
this.notifyDataSetChanged();
}
/**
* 删除数据
*/
public void removeData(int index){
this.datas.remove(index);
this.notifyDataSetChanged();
}
/**
* 删除所有数据
*/
public void removeAllData(){
this.datas.clear();
this.notifyDataSetChanged();
}
/**
* 获取当前的数据源,一般用于滑动监听加载下一页时用到,用来获取当前的长度。
* @return
*/
public List<T> getDatas() {
return this.datas;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null){
convertView = View.inflate(context,resId,null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
/**
* 抽象方法,用来给item的控件绑定数据
*/
bindData(datas.get(position), viewHolder,position);
return convertView;
}
/**
* 抽象方法,用来给item的控件绑定数据
*/
// public abstract void bindData(T data, ViewHolder holder);
public abstract void bindData(T data, ViewHolder holder, int position);
/**
* 优化,减少findViewById,降低性能消耗。
* 重用控件。
*/
public class ViewHolder {
/**
* 用来保存已经findViewByid的控件,用来重用,达到优化目的
*/
private Map<Integer, View> itemsCasher = new HashMap<Integer, View>();
private View parentView = null; // item的布局
public ViewHolder(View parentView) {
this.parentView = parentView;
}
/**
* 返回控件
* 如果map集合里面没有,就去findViewById到布局中找到,并且加入到集合中。
* 如果map集合存在,直接从map集合取。
* @param viewId
* @return
*/
public View getView(int viewId) {
View view = null;
if (itemsCasher.containsKey(viewId)) {
view = itemsCasher.get(viewId);
} else {
view = parentView.findViewById(viewId);
itemsCasher.put(viewId, view);
}
return view;
}
}
}
2,多布局:
package com.shenbin.lvgvbaseadapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装BaseAdapter
* 多布局适配器(也可用于单布局,
* 但是单布局的话,在重写getItemViewType(int position)时,
* 需要判断是否resId的长度,可以参考MyAdapter2这个类)
* Created by shenbin on 2015/12/25.
*/
public abstract class LvGvBaseAdapterMore<T> extends BaseAdapter {
private List<T> datas = new ArrayList(); //显示的数据
private int[] resId; //item布局文件的id(R.layout.item_lv)
private Context context; //上下文对象
public LvGvBaseAdapterMore(Context context, int... resId) {
this.resId = resId;
this.context = context;
}
/**
* 几个传入数据的方法
*
* @param datas
*/
public void setDatas(List<T> datas) {
this.datas.clear();
addDatas(datas);
}
public void addDatas(List<T> datas) {
this.datas.addAll(datas);
this.notifyDataSetChanged();
}
public void addOneData(T data) {
this.datas.add(data);
this.notifyDataSetChanged();
}
/**
* 删除数据
*/
public void removeData(int index){
this.datas.remove(index);
this.notifyDataSetChanged();
}
/**
* 删除所有数据
*/
public void removeAllData(){
this.datas.clear();
this.notifyDataSetChanged();
}
/**
* 获取当前的数据源,一般用于滑动监听加载下一页时用到,用来获取当前的长度。
*
* @return
*/
public List<T> getDatas() {
return this.datas;
}
/**
* 多布局还需要重写这两个方法
*
* @return
*/
@Override
public int getViewTypeCount() {
return resId.length;
}
/**
* 这个方法的返回值只能从0开始,否则会有一些莫名的错误,并且从0,开始递增(0,1,2,3,4),不能一下从0,2,4;
*
* 第一种方式:
* (这是采用映射的方式实现)
* 强制,T这个实体类中 必须有一个名字叫做type的属性
*
*
* 如果不理解的可以用第二种方式:
* 在自己的adapter中重写这个方法,自己去定义规则。
* 如:
*
* if( positon %2 ==0){
* return 0;
* }else{
* return 1;
* }
*
*
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
T data = datas.get(position);
Class c = data.getClass();
int ty = 0;
try {
Field type = c.getDeclaredField("type");
type.setAccessible(true);
ty = type.getInt(data);
} catch (Exception e) {
e.printStackTrace();
}
return ty;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
int type = getItemViewType(position);
if (convertView == null) {
convertView = View.inflate(context, resId[type], null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
/**
* 抽象方法,用来给item的控件绑定数据
*/
bindData(datas.get(position), viewHolder,position);
return convertView;
}
/**
* 抽象方法,用来给item的控件绑定数据
*/
public abstract void bindData(T data, ViewHolder holder,int position);
/**
* 优化,减少findViewById,降低性能消耗。
* 重用控件。
*/
public class ViewHolder {
/**
* 用来保存已经findViewByid的控件,用来重用,达到优化目的
*/
private Map<Integer, View> itemsCasher = new HashMap();
private View parentView = null; // item的布局
public ViewHolder(View parentView) {
this.parentView = parentView;
}
/**
* 返回控件
* 如果map集合里面没有,就去findViewById到布局中找到,并且加入到集合中。
* 如果map集合存在,直接从map集合取。
*
* @param viewId
* @return
*/
public View getView(int viewId) {
View view = null;
if (itemsCasher.containsKey(viewId)) {
view = itemsCasher.get(viewId);
} else {
view = parentView.findViewById(viewId);
itemsCasher.put(viewId, view);
}
return view;
}
}
}