博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android RecycleView Adapter简单封装
阅读量:6503 次
发布时间:2019-06-24

本文共 9529 字,大约阅读时间需要 31 分钟。

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

如下:

public class DetailParamAdapter extends RecyclerView.Adapter
{ private List
list; private LayoutInflater mInflater; private Context mContext = null; public DetailParamAdapter(Context context) { this.mContext = context; mInflater = LayoutInflater.from(context); } public void setList(List
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
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
extends RecyclerView.Adapter
implements RecyclerViewHelper
{ protected Context mContext; protected List
mList; protected int[] layoutIds; protected LayoutInflater mLInflater; private SparseArray
mConvertViews = new SparseArray<>(); public BaseRecycleAdapter(Context context, List
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
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
{ public ParamRecycleAdapter(Context context, List
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,相关资料请参照: ,代码已经上传(文章最后)。

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

public abstract class BasicAdapter
extends BaseAdapter { public Context mContext = null; protected LayoutInflater inflaterFactory = null; protected List
mList = new ArrayList
(); public BasicAdapter() { super(); } public BasicAdapter(Context context) { this.mContext = context; inflaterFactory = LayoutInflater.from(mContext); } public BasicAdapter(List
list) { if (list != null) { mList = list; } } public BasicAdapter(Context context, List
list) { this(context); this.mList = list; } public void setList(List
list) { if (list != null) { mList = list; notifyDataSetChanged(); } } public boolean addList(List
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
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
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 inflate(int resource, ViewGroup root, boolean attachToRoot) { if (inflaterFactory == null) { inflaterFactory = LayoutInflater.from(mContext); } return (V) inflaterFactory.inflate(resource, root, attachToRoot); } public
V inflate(int resource, ViewGroup root) { return inflate(resource, root, root != null); } public
V inflate(int resource) { return inflate(resource, null, false); }}
最后贴上RecycleView.Adapter的封装库地址:

你可能感兴趣的文章
三层架构
查看>>
Python变量类型(l整型,长整形,浮点型,复数,列表,元组,字典)学习
查看>>
解决方案(.sln)文件
查看>>
【Treap】bzoj1588-HNOI2002营业额统计
查看>>
第六周作业
查看>>
利用ZYNQ SOC快速打开算法验证通路(5)——system generator算法IP导入IP integrator
查看>>
指针和引用的区别
查看>>
运行PHP出现No input file specified错误解决办法
查看>>
【重建】从FJOI2016一试谈起
查看>>
selenium之frame操作
查看>>
php 引入其他文件中的变量
查看>>
MYSQL体系结构-来自期刊
查看>>
mysql的基本知识
查看>>
webpack入门(二)what is webpack
查看>>
UnitOfWork以及其在ABP中的应用
查看>>
学习C语言必须知道的理论知识(第一章)
查看>>
for语句内嵌例题与个人理解
查看>>
眠眠interview Question
查看>>
[转]CSS hack大全&详解
查看>>
RPC-client异步收发核心细节?
查看>>