android RecycleView Adapter简单封装
2016-10-29 17:48
357 查看
早些时候我们使用系统提供个的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);
}
然后我们需要绑定界面了,由于各个页面的对于的元素不一样,所以这个方法我们需要根据实际情况去动态绑定数据,所以我们需要写一个抽象方法去让用户实现,这个抽象方法主要包含ViewHolder界面,位置,还有Item的元素(其实这个大可以不要)protected abstract void onBindData(BaseRecycleHolder viewHolder, int position, T 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的封装库地址:点击打开链接
如下:
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简单封装
- android RecycleView Adapter简单封装
- android:RecycleView的简单封装使用
- Android-万能 Adapter 封装(实现textview,imageView 的简单封装,封装 jar 包)
- [置顶] 超级简单RecycleViewAdapter的封装-支持多视图,多点击回调
- 简单的封装BaseRecycleviewAdapter
- 超级简单RecycleViewAdapter的封装-支持多视图,多点击回调
- 超级简单RecycleViewAdapter的封装-支持多视图,多点击回调
- Android--RecycleView的简单实用
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- RecyclerView.Adapter 的简单封装
- Android RecyclerView Adapter及Holder的封装【原创】
- Android之---RecycleView实现简单的图片查看功能(类似相册查看器)
- 简单封装RecyclerView的Adapter
- Android-对ListView的Adapter的一种简单封装
- Android开发之ButterKnife,GreenDao简单运用,以及推荐并使用一个好用的开源库BaseRecyclerViewAdapterHelper。
- android开发 RecycleView之No adapter attached; skipping layout
- android--RecycleView.Adapter的初体验
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- RecycleView Adapter的封装