实现(ListView/GridView等)万能数据适配器

 2016年5月25日修改:之前有朋友留言说是报nullPoint异常,问题确实存在。因最近工作忙,一直没有来得及改。
 今天在工作中正好用这个万能工具类,所以把代码简单改了下。多谢朋友指正!
   List,View,GridView等列表展示控件是我们在项目中不可或缺的一部分,而且在项目中
  用到的地方肯定不止一两个地方,好的项目,大的项目可能要用到几十上百个ListView。 
  我们知道要实现ListView加载数据,就需要给ListView写数据适配器Adapter,
  通常我们是根据需求,为不同的ListView为不同的Adapter,这个Adapter需要extends
  BaseAdapter,这种 常规写法对我们来说轻车熟路,但是我们真要为项目中几十上百个
  ListView写几十上面个Adapter extend BaseAdapter吗?那我们肯定不加班熬死
  也累死了。我们项目中通常会写一个通用的CommonAdapter,然后在我们每一个ListView
  中写一个Adapter extends CommonAdapter来减少代码。这几天项目发版本,bug不多,
  又学习了下大神们讲的课程,今天我们就记录下实现一个通用的超级Adapter,释放我们的惰性。
      优化ListView少不了ViewHolder,首先实现一个通用的ViewHolder
public class ViewHolder {
    /**
     * SparseArray是android里为<Interger,Object>这样的HashMap<Integer,Oject>
     * 而专门写的类,目的是提高效率,其核心是折半查找函数(binarySearch)。
     * 在Android中,当我们需要定义    HashMap<Integer, E> hashMap =
     * new HashMap<Integer, E>()时我们可以使用如下的方式来取得更好的性能.
     * SparseArray<E> sparseArray = new SparseArray<E>();
     */
    private SparseArray<View> mViews;
    private int mPosition;// 这个参数在我们防止数据错乱加载时可用到
    private View mConvertView;
    private Context mContext;

    public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
        this.mPosition = position;
        this.mContext = context;
        mViews = new SparseArray<>();
        mConvertView = LayoutInflater.from(mContext).inflate(layoutId, parent, false);
        mConvertView.setTag(this);
    }

    /**
     * 获取到ViewHolder
     *
     * @description:
     * @author ldm
     * @date 2015-10-13 上午10:08:41
     */
    public static ViewHolder getHolder(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
        if (convertView == null) {
            return new ViewHolder(context, parent, layoutId, position);
        } else {
            ViewHolder hoder = (ViewHolder) convertView.getTag();
            hoder.mPosition = position;
            return hoder;
        }
    }

    public View getConvertView() {
        return mConvertView;
    }

    /**
     * 通过id获取控件
     *
     * @description:
     * @author ldm
     * @date 2015-10-12 下午8:01:46
     */
    public <T extends View> T getViewById(int resId) {
        View view = mViews.get(resId);
        if (view == null) {
            view = mConvertView.findViewById(resId);
            mViews.put(resId, view);
        }
        return (T) view;
    }


    /**
     * 设置TextView数据
     *
     * @description:
     * @author ldm
     * @date 2015-10-13 上午9:32:49
     */
    public ViewHolder setTextView(int resId, String text) {
        TextView tv = getViewById(resId);
        tv.setText(text);
        return this;
    }

    public ViewHolder setTextView(int resId, int textId) {
        TextView tv = getViewById(resId);
        tv.setText(textId);
        return this;
    }

    /**
     * 为ImageView设置数据
     *
     * @description:
     * @author ldm
     * @date 2015-10-13 上午9:34:14
     */
    public ViewHolder setImageView(int resId, int picId) {
        ImageView iv = getViewById(resId);
        iv.setImageResource(picId);
        return this;
    }
    // 可以根据自己需要写其它的组件
}

写一个通用的CommonAdapter与ViewHolder结合起来

/**
 * 通用Adapter,我们为ListView写的数据适配adapter需要继承这个类
 * @description:
 * @author ldm
 * @date 2015-10-13 上午10:12:05
 */
public abstract class CommonAdapter<T> extends BaseAdapter {
    protected Context mContext;
    protected List<T> mDatas;
    protected LayoutInflater mInflater;
    protected int itemResId;

    public CommonAdapter(Context mContext, List<T> mDatas, int itemResId) {
        this.mContext = mContext;
        this.mDatas = mDatas;
        this.itemResId = itemResId;
        mInflater = LayoutInflater.from(mContext);
    }

    @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 holder = ViewHolder.getHolder(mContext, convertView, parent, itemResId, position);
        convert(holder, getItem(position));
        return holder.getConvertView();
    }

    /**
    * 数据处理方法,我们写的ListView对应adapter主要是实现这个方法功能
    * @description:
    * @author ldm
    * @date 2015-10-13 上午10:13:06
    */
    public abstract void convert(ViewHolder holder, T t);
}

当我们要使用的时候 ,定义好数据 实体类TestBean

// 我们为ListView写的adapter就只需要实现 下面这么几行代码
public class MyAdapter extends CommonAdapter<TestBean> {
    public MyAdapter(Context mContext, List<TestBean> mDatas, int resId) {
        super(mContext, mDatas, resId);
    }

    @Override
    public void convert(ViewHolder holder, TestBean bean) {
        holder.setTextView(R.id.item_name, t.getTitle());// 为item中的TextView设置数据
        holder.setImageView(R.id.item_desc, R.drawable.ic_launcher);// 为item中的ImageView设置数据
    }
}

在Activity中使用到的代码

private void initViews() {
    this.mListView = (ListView) findViewById(R.id.test_lv);
    mAdapter=new MyAdapter(this,mDatas,R.layout.listview_item);
    this.mListView.setAdapter(mAdapter);
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值