Android 简单的MyBaseAdapter

在Android开发中经常用到ListView列表,于是Adapter也就比较常用的了, 而实际项目中稍微复杂点的基本都会用到BaseAdapter, 大家都知道继承自BaseAdapter必须要重写getCount(), getItem(), getItemId(), getView()这几个方法, 而且可能为了优化列表的加载还还会经常采用ViewHoder模式, 试想列表多了估计都写烦了吧,那么今天就来来一种通用、简洁的Adapter,以后你就可以几行代码搞定一个复杂的Adapter了。

通用的SimpleBaseAdapter

首先我们来解决每次都重写BaseAdapter的那几个方法的问题,解决方案很简单,直接写一个抽象的MyBaseAdapter,代码如下

package cn.wangxn.app.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.List;

/**
 *
 * @Description:
 * @Title: MyBaseAdapter
 * @author: wangxn
 * @date: 2015/6/29
 *
 *  泛型  T : 对应javaBean的类型
 *       E : 对应 ViewHolder的类型
 */
public abstract class MyBaseAdapter<T, E> extends BaseAdapter {

    private Class<E> holderClass; //ViewHolder类的Class
    private E holder;             //ViewHolder的实例
    private List<T> list;         //adapter对应的数据集合
    private Context context;      //上下文
    private int resLayoutId;      //条目资源的布局id

    /**
     *构造方法   必须是有4个参数的构造方法
     *@param list         对应javabean的集合的引用
     *@param context      对应上下文
     *@param c            对应ViewHolder的Class,
     *@param resLayoutId  对应的是条目Item的布局资源id
     */
    public MyBaseAdapter(List<T> list, Context context, Class<E> c, int resLayoutId) {
        this.list = list;
        this.context = context;
        this.resLayoutId = resLayoutId;
        this.holderClass = c;
    }

    @Override
    public int getCount() {
        if (list != null && list.size() > 0) {
            return list.size();
        }
        return 0;
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        E holder = null;    //申明ViewHolder类实例
        if (convertView == null) {   
            convertView = View.inflate(context, resLayoutId, null);   //获取到convertView
            try {
                holder = getObject(holderClass);            //对viewHolder进行实例化
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }

            if (holder != null){               
                findHolderViews(convertView, holder);     // 找到convertView布局中的各种控件
                convertView.setTag(holder);            //将viewHolder设置为convertView的tag,重复利用
            }
        } else {
            holder = (E) convertView.getTag();         //从convertView的tag中拿去内容转化成viewHolder
        }

        T bean = list.get(position);                 //拿取单条数据

        if (holder != null) {
            setHolderView(holder, bean);            //将单条数据和holder中对应的内容进行绑定,以及设置
        }

        return convertView;           //返回convertView
    }

    /**
    *抽象方法,需要自己实现, 将集合中的单挑数据javaBean和 布局进行绑定设置
    */
    protected abstract void setHolderView(E holder, T bean);  

    /**
    *抽象方法,需要自己实现, 需要找到布局中的各个控件,findViewById
    */
    protected abstract void findHolderViews(View convertView, E holder);
    
    /**
    *  实例化ViewHolder对象需要调用的方法,
    *  ViewHolder对象需要提供默认的无参构造方法
    */
    private <T> T getObject(Class<T> c) throws IllegalAccessException, InstantiationException {
        T  t = c.newInstance();
        return t;
    }
}


要使用这个MyBaseAdapter,

  1. 需要继承MyBaseAdapter, 需要实现2个抽象方法,

    1.   protected abstract void setHolderView(E holder, T bean){
        }
        protected abstract void findHolderViews(View convertView, E holder){
        }

      需要实现由4个参数的构造方法.

    2.  public MyBaseAdapter(List<T> list, Context context, Class<E> c, int resLayoutId) {
          super(list,context,c,resLayoutId);
       }
  2. 同时需要提供2个泛型类型

    1. javaBean        //对应数据

    2. ViewHolder   //对应布局中的控件


一个实现的例子:

public class TradeListAdapter extends MyBaseAdapter<TradeDetail, TradeDetailHolder> {

    public TradeListAdapter(List<TradeDetail> list, Context context, Class<TradeDetailHolder> holderClass, int resLayoutId) {
        super(list, context, holderClass, resLayoutId);
    }

    @Override
    protected void setHolderView(TradeDetailHolder holder, final TradeDetail bean) {
        StringBuilder sb = new StringBuilder("");
        if (!StrUtil.isEmpty(bean.carBrandName)) {
            sb.append(bean.carBrandName);
            if (!StrUtil.isEmpty(bean.carSubBrandName)) {
                sb.append(bean.carSubBrandName);
                if (!StrUtil.isEmpty(bean.carTypeName)) {
                    sb.append(bean.carTypeName);
                }
            }
        }
        holder.tv_car_name.setText(sb.toString());

        if (!StrUtil.isEmpty(bean.tradeAmount)) {
            holder.tv_rent_price.setText("¥" + bean.tradeAmount);
        } else {
            holder.tv_rent_price.setText("");
        }

        if (!StrUtil.isEmpty(bean.tradeDate)) {
            holder.tv_date_time.setText(bean.tradeDate);
        } else {
            holder.tv_date_time.setText("");
        }

        if (!StrUtil.isEmpty(bean.orderId)) {
            holder.btn_detail.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Bundle bundle = new Bundle();
                    bundle.putString("orderId", bean.orderId);
                    startActivity(OrderDetailActivity.class, bundle);
                }
            });
        }
    }

    @Override
    protected void findHolderViews(View contaier, TradeDetailHolder holder) {
        holder.tv_car_name = (TextView) contaier.findViewById(R.id.tv_car_name);
        holder.tv_rent_price = (TextView) contaier.findViewById(R.id.tv_rent_price);
        holder.tv_date_time = (TextView) contaier.findViewById(R.id.tv_date_time);
        holder.btn_detail = (Button) contaier.findViewById(R.id.btn_detail);
    }
}

用到的TradeDetailHolder

import android.widget.Button;
import android.widget.TextView;

public class TradeDetailHolder {
    public TradeDetailHolder() { //提供下默认的构造方法,防止有些时候报错,
    }
    public TextView tv_car_name;
    public TextView tv_rent_price;
    public TextView tv_date_time;
    public Button btn_detail;
}

用到的javaBean:TradeDetail

public class TradeDetail { 
    public String orderId;// string 订单ID
    public String orderNumber; // string 订单编号
    public String carBrandName;   // string 品牌
    public String carSubBrandName; // string 二级品牌
    public String carTypeName;    // string 型号
    public String tradeAmount;  //  string 价格
    public String tradeDate;//  string 日期
}


好处:

    这样之后,可以省去那些每一个BaseAdapter都要写的方法getCount(), getItem(), getItemId(), getView()

只关注最核心的数据和界面控件之间的逻辑处理,这部分逻辑处理全部在

setHolderView(JAVABEAN b, VIEWHOLDER holder)

这个方法里去实现.

而方法

 protected void findHolderViews(View convertView, ViewHolder holder)

主要是为了获取到布局中的控件,这个也只能自己手动获取了

你可能感兴趣的:(Android 简单的MyBaseAdapter)