早些时候我们使用系统提供个的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. HDU 4787 GRE Words Revenge

    Description Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. ...

  2. hdu 5430(几何)

    题意:求光在圆内反射n次后第一次返回原点的方案数 如果k和n-1可约分,则表明是循环多次反射方案才返回原点. #include <iostream> #include <cstrin ...

  3. Codeforces Round#433 简要题解

    来自FallDream的博客,未经允许,请勿转载,谢谢. 我的号自从几个月前姿势水平过低疯狂掉分之后就没动过了  突然想上点分  就打了一场Div1  没想到打到了rank5  一发上橙了,可还行. ...

  4. P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

    1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...

  5. Python中模块之logging & subprocess的讲解

    subprocess & logging模块的介绍 1. subprocess 该模块替代了os.system & os.pawn*所实现的功能. 2. logging 1. 日志五大 ...

  6. 5步做一个 TensorFlow 聊天机器人:DeepQA

    项目截图: 实测截图: 一步一步教程: 1.下载这个项目: https://github.com/Conchylicultor/DeepQA 2.下载训练好的模型: https://drive.goo ...

  7. mac下怎么删除隐藏文件比如 .Trashes文件

    U盘和移动硬盘接入Mac时会产生.Trashes,.Spotlight-V100,.fseventsd等文件 每插入Mac一次,都会检查是否有这些文件,如果没有,就会创建这些文件 特别是有时候,在文件 ...

  8. 分布式改造剧集之Redis缓存采坑记

    Redis缓存采坑记 ​ 前言 ​ 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...

  9. Postgresql查询最近12个月、最近30天数据

    -- 最近 12 个月 SELECT * FROM 表名 WHERE 日期字段 BETWEEN (now() - INTERVAL '12 months') AND now() -- 最近 30 天 ...

  10. Linux系统中安装Oracle过程记录

    第一章 安装数据库软件 1.1 修改密码及创建目录和权限 创建oracle用户和组 创建相关目录并赋权 1.2 设置oracle用户环境变量 ORACLE_BASE:产品基目录 ORACLE_HOME ...