早些时候我们使用系统提供个的BaseAdapter的时候为了满足大家的需要,我们总会对BaseAdapter做一层上层的封装,然后对于实际业务我们只需要关心getView里面的View即可,是代码可读性和可维护性更高,特别是在多View的界面,这个优势就体现出来了,自从Android 5.0后系统提供的,先不说效率如何,这个既然是Google为我们提供的,我们姑且用之,不过说实话,对于它的写法不习惯他的人看着很是麻烦,其实这个类无外乎继承自RecyclerView.Adapter然后提供一个HolderView。

如下:

public class DetailParamAdapter extends RecyclerView.Adapter<ParamHolderView> {

    private List<ProductParamEntity> list;
    private LayoutInflater mInflater;
    private Context mContext = null;

    public DetailParamAdapter(Context context) {
        this.mContext = context;
        mInflater = LayoutInflater.from(context);
    }

    public void setList(List<ProductParamEntity> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    public OnItemClickListener mOnItemClickListener;

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener mOnItemClickLitener) {
        this.mOnItemClickListener = mOnItemClickLitener;
    }

    @Override
    public ParamHolderView onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.item_product_param, parent, false);
        ParamHolderView holder = new ParamHolderView(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final ParamHolderView holder, final int position) {
        ProductParamEntity bean = list.get(position);
        if (bean != null) {
            holder.itemTitle.setText(bean.title);
            holder.itemContent.setText(bean.content);
        }

    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}

class ParamHolderView extends RecyclerView.ViewHolder {

    @BindView(R.id.item_title)
    TextView itemTitle;
    @BindView(R.id.item_content)
    TextView itemContent;

    public ParamHolderView(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
        itemView.setTag(this);
    }

}

不过我们可不可以对上面的写法来一个精简呢?

其实分析下,adapter对我们有用的就两个方法,一个是获取adapter的View,然后是绑定数据OnBindData,至于数据的来源,我们可以借鉴RecyclerView.Adapter做一个泛型。

有了上面的思路,首先我们要获取adapter的View,然后将它赋给onCreateViewHolder返回的view对象。所以我们的构造可以这么写,

public BaseRecycleAdapter(Context context, List<T> list, int... layoutIds) {
        this.mContext = context;
        this.mList = list;
        this.layoutIds = layoutIds;
        this.mLInflater = LayoutInflater.from(mContext);
    }

 public BaseRecycleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType < 0 || viewType > layoutIds.length) {
            throw new ArrayIndexOutOfBoundsException("layoutIndex");
        }
        if (layoutIds.length == 0) {
            throw new IllegalArgumentException("not layoutId");
        }
        int layoutId = layoutIds[viewType];
        View view = mConvertViews.get(layoutId);
        if (view == null) {
            view = mLInflater.inflate(layoutId, parent, false);
        }
        BaseRecycleHolder viewHolder = (BaseRecycleHolder) view.getTag();
        if (viewHolder == null || viewHolder.getLayoutId() != layoutId) {
            viewHolder = new BaseRecycleHolder(mContext, layoutId, view);
            return viewHolder;
        }
        return viewHolder;
    }

然后我们需要绑定界面了,由于各个页面的对于的元素不一样,所以这个方法我们需要根据实际情况去动态绑定数据,所以我们需要写一个抽象方法去让用户实现,这个抽象方法主要包含ViewHolder界面,位置,还有Item的元素(其实这个大可以不要)

protected abstract void onBindData(BaseRecycleHolder viewHolder, int position, T item);

@Override
    public void onBindViewHolder(BaseRecycleHolder holder, int position) {
        final T item = mList.get(position);
        onBindData(holder, position, item);
    }

当然我们这个Adapter基础的类可能还需要一些常用入add,clear,del等操作方法。其完整的代码如下:

public abstract class BaseRecycleAdapter<T> extends RecyclerView.Adapter<BaseRecycleHolder> implements RecyclerViewHelper<T> {

    protected Context mContext;
    protected List<T> mList;
    protected int[] layoutIds;
    protected LayoutInflater mLInflater;

    private SparseArray<View> mConvertViews = new SparseArray<>();

    public BaseRecycleAdapter(Context context, List<T> list, int... layoutIds) {
        this.mContext = context;
        this.mList = list;
        this.layoutIds = layoutIds;
        this.mLInflater = LayoutInflater.from(mContext);
    }

    @Override
    public BaseRecycleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType < 0 || viewType > layoutIds.length) {
            throw new ArrayIndexOutOfBoundsException("layoutIndex");
        }
        if (layoutIds.length == 0) {
            throw new IllegalArgumentException("not layoutId");
        }
        int layoutId = layoutIds[viewType];
        View view = mConvertViews.get(layoutId);
        if (view == null) {
            view = mLInflater.inflate(layoutId, parent, false);
        }
        BaseRecycleHolder viewHolder = (BaseRecycleHolder) view.getTag();
        if (viewHolder == null || viewHolder.getLayoutId() != layoutId) {
            viewHolder = new BaseRecycleHolder(mContext, layoutId, view);
            return viewHolder;
        }
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(BaseRecycleHolder holder, int position) {
        final T item = mList.get(position);
        onBindData(holder, position, item);
    }

    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }

    @Override
    public int getItemViewType(int position) {
        return getLayoutIndex(position, mList.get(position));
    }

    /**
     * 指定item布局样式在layoutIds的索引。默认为第一个
     */
    public int getLayoutIndex(int position, T item) {
        return 0;
    }

    protected abstract void onBindData(BaseRecycleHolder viewHolder, int position, T item);

    @Override
    public boolean addAll(List<T> list) {
        boolean result = mList.addAll(list);
        notifyDataSetChanged();
        return result;
    }

    @Override
    public boolean addAll(int position, List list) {
        boolean result = mList.addAll(position, list);
        notifyDataSetChanged();
        return result;
    }

    @Override
    public void add(T data) {
        mList.add(data);
        notifyDataSetChanged();
    }

    @Override
    public void add(int position, T data) {
        mList.add(position, data);
        notifyDataSetChanged();
    }

    @Override
    public void clear() {
        mList.clear();
        notifyDataSetChanged();
    }

    @Override
    public boolean contains(T data) {
        return mList.contains(data);
    }

    @Override
    public T getData(int index) {
        return mList.get(index);
    }

    @Override
    public void modify(T oldData, T newData) {
        modify(mList.indexOf(oldData), newData);
    }

    @Override
    public void modify(int index, T newData) {
        mList.set(index, newData);
        notifyDataSetChanged();
    }

    @Override
    public boolean remove(T data) {
        boolean result = mList.remove(data);
        notifyDataSetChanged();
        return result;
    }

    @Override
    public void remove(int index) {
        mList.remove(index);
        notifyDataSetChanged();
    }
}

当然这里还有好多的辅助类,这里就不在详解解释了,那最好我们怎么用呢?很简单,来一个之前的例子:

public class ParamRecycleAdapter extends BaseRecycleAdapter<ProductParamEntity> {

    public ParamRecycleAdapter(Context context, List<ProductParamEntity> list) {
        super(context, list, R.layout.item_product_param);
    }

    @Override
    protected void onBindData(BaseRecycleHolder viewHolder, int position, ProductParamEntity item) {
        viewHolder.setText(R.id.item_title, item.title)
                .setText(R.id.item_content, item.content);
    }
}

我们只要注意上面标颜色的部分即可。我已经将这个封装为一个库文件,如果有需要的可以自己打包aar或者jar,相关资料请参照:打包aar,代码已经上传(文章最后)。

对于之前的Baseadapter这里也贴给大家:

public abstract class BasicAdapter<T> extends BaseAdapter {
    public Context mContext = null;
    protected LayoutInflater inflaterFactory = null;
    protected List<T> mList = new ArrayList<T>();

    public BasicAdapter() {
        super();
    }

    public BasicAdapter(Context context) {
        this.mContext = context;
        inflaterFactory = LayoutInflater.from(mContext);
    }

    public BasicAdapter(List<T> list) {
        if (list != null) {
            mList = list;
        }
    }

    public BasicAdapter(Context context, List<T> list) {
        this(context);
        this.mList = list;
    }

    public void setList(List<T> list) {
        if (list != null) {
            mList = list;
            notifyDataSetChanged();
        }
    }

    public boolean addList(List<T> list) {
        if (list != null && list.size() > 0) {
            mList.addAll(list);
            notifyDataSetChanged();
            return true;
        }
        return false;
    }

    public boolean add(T t) {
        if (t != null) {
            mList.add(t);
            notifyDataSetChanged();
            return true;
        }
        return false;
    }

    public boolean add(int position, T t) {
        if (t != null && getCount() >= position) {
            mList.add(position, t);
            notifyDataSetChanged();
            return true;
        }
        return false;
    }

    public void remove(T t) {
        if (mList.remove(t)) {
            notifyDataSetChanged();
        }
    }

    public void remove(List<T> list) {
        if (mList.remove(list)) {
            notifyDataSetChanged();
        }
    }

    public void remove(int index) {
        if (index >= 0 && index < mList.size()) {
            mList.remove(index);
            notifyDataSetChanged();
        }
    }

    public void clear() {
        if (mList != null) {
            mList.clear();
            notifyDataSetChanged();
        }
    }

    public List<T> getList() {
        return mList;
    }

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

    @Override
    public T getItem(int position) {
        if (mList!=null){
            return mList.get(position);
        }else
            return null;
    }

    public T getLastItem() {
        if (mList.size() > 0) {
            return mList.get(mList.size() - 1);
        }
        return null;
    }

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

    public <V extends View> V inflate(int resource, ViewGroup root, boolean attachToRoot) {
        if (inflaterFactory == null) {
            inflaterFactory = LayoutInflater.from(mContext);
        }
        return (V) inflaterFactory.inflate(resource, root, attachToRoot);
    }

    public <V extends View> V inflate(int resource, ViewGroup root) {
        return inflate(resource, root, root != null);
    }

    public <V extends View> V inflate(int resource) {
        return inflate(resource, null, false);
    }
}

最后贴上RecycleView.Adapter的封装库地址:点击打开链接

android RecycleView Adapter简单封装的更多相关文章

  1. Android ToolBar 的简单封装

    使用过 ToolBar 的朋友肯定对其使用方法不陌生,由于其使用方法非常easy.假设对 ActionBar 使用比較熟练的人来说.ToolBar 就更easy了!只是,相信大家在使用的过程中都遇到过 ...

  2. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  3. Android -- OkHttp的简单使用和封装

    1,昨天把okHttp仔细的看了一下,以前都是调用同事封装好了的网络框架,直接使用很容易,但自己封装却不是那么简单,还好,今天就来自我救赎一把,就和大家写写从最基础的OKHttp的简单get.post ...

  4. android代码优化----ListView中自定义adapter的封装(ListView的模板写法)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  5. [Android] Android RecycleView和ListView 自定义Adapter封装类

    在网上查看了很多对应 Android RecycleView和ListView 自定义Adapter封装类 的文章,主要存在几个问题: 一).网上代码一大抄,复制来复制去,大部分都运行不起来,或者 格 ...

  6. Adapter的封装之路

    原文:Adapter的封装之路 一.几种常见列表效果: 假如要用RecyclerView实现下面的几种效果,你会如何实现呢? 效果1:单布局效果   效果2:多布局效果 有多种Item布局   效果3 ...

  7. Android--Retrofit+RxJava的简单封装(三)

    1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...

  8. 安卓控件RecycleView的简单使用

    RecycleView的使用 目录 RecycleView的使用 技术概述 技术详述 遇到问题和解决 总结 参考文献 技术概述 RecycleView是谷歌官方对ListView的改进(并不是替代), ...

  9. Android之Adapter用法总结-(转)

    Android之Adapter用法总结 1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(List View,Grid Vie ...

随机推荐

  1. NOIP2014-10-30模拟赛

    T1:逗比三角形 [题目描述] 小J是一名OI退役滚粗文化课选手,他十分喜欢做题,尤其是裸题.他现在有一个二维盒子和一些二维三角形,这个盒子拥有无限的高度和L的宽度.而且他的三角形也都是一些锐角三角形 ...

  2. Spring学习笔记2——创建Product对象,并在其中注入一个Category对象

    第一步:创建Product类.在Product类中有对Category对象的set和get方法 package com.spring.cate; public class Product { priv ...

  3. Delphi 日期时间函数

    DateUtils.IncYear();DateUtils.IncMonth();DateUtils.IncWeek();DateUtils.IncDay();DateUtils.IncHour(); ...

  4. GC其他:引用标记-清除、复制、标记-整理的说明

    对象死亡历程 1.基本的mark&sweep是必须的,后续的都是对他的改进, 2.young代理的survivor就是使用了复制算法,避免碎片 3.还有标记整理算法(压缩),就是将存活的对象移 ...

  5. Lucene——Field.Store(存储域选项)及Field.Index(索引选项)

    Field.Store.YES或者NO(存储域选项) 设置为YES表示或把这个域中的内容完全存储到文件中,方便进行文本的还原 设置为NO表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完 ...

  6. Matlab 编译EXE

    环境:vs2013  matlab2015b 一.生成独立可执行的程序(exe文件)步骤1.设置编译器.在matlab命令行输入mbuild –setup以及mex –setup,选择安装的c编译器. ...

  7. 服务器&阵列卡&组raid 5

    清除raid信息后,机器将会读不到系统, 后面若进一步操作处理, raid信息有可能会被初始化掉,那么硬盘数据就有可能会被清空, 导致数据丢失, 否则如果只是清除raid信息,重做raid是可以还原系 ...

  8. Node.js 集群

    稳定性: 2 - 不稳定 单个 Node 实例运行在一个线程中.为了更好的利用多核系统的能力,可以启动 Node 集群来处理负载. 在集群模块里很容易就能创建一个共享所有服务器接口的进程. var c ...

  9. Python3 数据结构

    列表 Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能. 以下是 Python 中列表的方法: 方法 描述 list.append(x ...

  10. Ubuntu命令行启动Matlab

    原文转自:http://blog.csdn.net/striker_v/article/details/52884485 小编安装的是Matlab R2015b,使用的是默认安装目录,安装在目录/us ...