之前在学校学习的时候,接触的项目不多没发现,工作之后用到ListView多了很多,不停地写Adapter写的真心烦..后来看到hongyang大神的博客,自己分析又新增了一些内容,让新手学习更容易…
public ViewHolder{
private SparseArray mViews;
protected int mPosition;
private View mConvertView;
private Context mContext;
protected int mLayoutId;
public ViewHolder(Context context, View itemView, ViewGroup parent, int position)
{
mContext = context;
mConvertView = itemView;
mPosition = position;
mViews = new SparseArray();
mConvertView.setTag(this);
}
...
public static ViewHolder get(Context context, View convertView,
ViewGroup parent, int layoutId, int position)
{
if (convertView == null)
{
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
ViewHolder holder = new ViewHolder(context, itemView, parent, position);
holder.mLayoutId = layoutId;
return holder;
} else
{
ViewHolder holder = (ViewHolder) convertView.getTag();
//复用ConvertView时,position 是会发发生变化的,这里需要更新一下
holder.mPosition = position;
return holder;
}
}
public View getConvertView()
{
return mConvertView;
}
public T getView(int viewId)
{
View view = mViews.get(viewId);
if (view == null)
{
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
public abstract class CommonAdapter<T> extends BaseAdapter {
protected List mDatas;
protected Context mContext;
protected int mLayoutID;
/**
* @param context 上下文
* @param layoutID_item item 布局ID
* @param datas List bean类数组
*/
public CommonAdapter(Context context, final int layoutID_item, List datas) {
this.mContext = context;
this.mDatas = datas;
this.mLayoutID = layoutID_item;
}
@Override
public int getCount() {
//判空,防止空指针异常
if (mDatas != null) {
return mDatas.size();
} else {
return 0;
}
}
@Override
public T getItem(int position) {
//判空,防止空指针异常
if (mDatas != null) {
return mDatas.get(position);
} else {
return null;
}
}
@Override
public long getItemId(int position) {
return position;
}
/**
* ItemInfo infos = mDatas.get(position);
* holder.setText(R.id.tv_title, infos.getTitle());
* holder.setText(R.id.tv_desc, infos.getDesc());
* holder.setText(R.id.tv_data, infos.getData());
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.get(mContext, convertView, parent, mLayoutID, position);
convert(holder, getItem(position), position);
return holder.getConvertView();
}
/**
* 分析得知需要Item,holder,position
*
* @param holder
* @param item
* @param position
*/
protected abstract void convert(ViewHolder holder, T item, int position);
}
https://github.com/hongyangAndroid/baseAdapter
配合该视频教程使用更佳:
http://www.imooc.com/video/7264
几个关键方法分析:
判断外面传进来的item对象和对应的item postion(true 为同一类型,false为不同类型)
默认为false
mlistView.setAdapter(new CommonAdapter(this, R.layout.item_list, mDatas) {
@Override
protected void convert(ViewHolder viewHolder, String item, int position) {
viewHolder.setText(R.id.tv, item);
}
});
**每种Item对应一个ItemViewDelagate:**
MultiItemTypeAdapter adapter = new MultiItemTypeAdapter(this,mDatas);
adapter.addItemViewDelegate(new MsgSendItemDelagate());
adapter.addItemViewDelegate(new MsgComingItemDelagate());
1.TextView的各种属性值
2.事件监听
...
问题:ListView中的Item中有checkBox控件时,item不能被点击,check可以
原因:看ListView源码可知,当Item中有占用焦点的控件,Item失去焦点
解决1:checkBox.setFocusable="false"
解决2:Item的根部局 android:descendantFocusability="blocksDescendants"
解决1:在bean类记录下当前这个控件的状态(checkBox为例)
在bean类 ItemInfo 设置一个isChecked 的boolean值
final CheckBox checkBox=holder.getViewByID(cb);
checkBox.setChecked(item.isChecked());
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
item.setChecked(checkBox.isChecked());
}
});
解决2: 写一个数组记录位置(CheckBox为例)
final List mPos = new ArrayList();
final CheckBox checkBox = holder.getViewByID(cb);
//初始化checkBox时,先默认全部为false,数组拿到关系再设置为
checkBox.setChecked(false);
if(mPos.contains(holder.getPosition())){
checkBox.setChecked(true);
}
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkBox.isChecked()) {
mPos.add(holder.getPosition());
} else {
//注意是移除对象
mPos.remove((Integer) holder.getPosition());
}
}
});
public ViewHolder setImageUrl(int viewId,String url){
ImageView view = getViewByID(viewId);
//Imageloader.getInstance().loadImg(view,url);
return this;
}
源码先不上了,完善ListView 中能添加多种类型Item再补上