RecyclerView 的简单封装
2016-12-11 17:02
417 查看
1 前言
最近在学习Material Design设计,首当其冲就是学习RecyclerView,参考了下Hongyang自己对RecyclerView的ViewHolder与Adapter做了下简单的封装。下面,废话不多说,直接上干货。2 ViewHolder的封装
ViewHolder在RecyclerView中的作用主要就是用来缓存我们每一个Item对应的View视图的,我们在Adapter中主要是在public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)回去创建一个ViewHolder,在 public void onBindViewHolder(ViewHolder holder, int position)会将holder与该position处的数据进行绑定(就是设置数据该怎么显示,这里需要访问ViewHolder中缓存的View)。基于此我们可以总结出ViewHolder的基本功能:1 提供创建ViewHolder的功能
这里主要包括两种,一种是直接传入一个View参数创建一个View,比如我们在ListView中经常使用的下面代码:
View view = LayoutInflater.from(mContext).inflate(R.layout.xxx,parent,false); ViewHolder holder = new ViewHolder(view);
第二种就是直接传入一个layoutId,这一种我们在多种ItemType类型中经常会用到。
2 对ViewHolder中各种View的访问
一般ViewHolder中会有TextView,ImageView等,我们通过使用一个SparseArray来缓存我们加载过的View,我们经常需要对它设置文本内容,字体大小,图片内容等。
3 封装ViewHolder中各种View事件
一般主要是点击事件与长按事件,我这里只封装了点击事件
下面直接上封装好的ViewHolder
/** * Created by qiyei2015 on 2016/11/28. * 1273482124@qq.com */ public class ViewHolder extends RecyclerView.ViewHolder { private Context mContext; private SparseArray<View> mViews;//存储View,key 为int,value为View类型 private View mConvertView; //存储加载布局xml中的的所有View public ViewHolder(Context context,View view){ super(view); mContext = context; mConvertView = view; mViews = new SparseArray<>(); } /** * 创建ViewHolder,外部调用 * @param context * @param view * @return */ public static ViewHolder createViewHolder(Context context,View view){ return new ViewHolder(context,view); } /** * 创建ViewHolder * @param context * @param parent * @param layoutId * @return */ public static ViewHolder createViewHolder(Context context, ViewGroup parent,int layoutId){ View itemView = LayoutInflater.from(context).inflate(layoutId,parent,false); return new ViewHolder(context,itemView); } /** * 根据id来查找View * @param viewId * @param <T> * @return */ public <T extends View> T getView(int viewId){ View view = mViews.get(viewId); if (view == null){ //如果缓存里面没有,就从布局文件中查找 view = mConvertView.findViewById(viewId); //从xml查找的,减少重复调用findViewById mViews.put(viewId,view); } return (T) view; } /** * 获取ConvertView * @return */ public View getConvertView(){ return mConvertView; } /** * 以下是设置TextView,imageView等View的一些常用方法 * */ /** * 设置Text * @param viewId * @param text * @return */ public ViewHolder setText(int viewId,CharSequence text){ TextView view = getView(viewId); view.setText(text); return this; } /** * 设置ImageView * @param viewId * @param resId * @return */ public ViewHolder setImageResource(int viewId,int resId){ ImageView view = getView(viewId); view.setImageResource(resId); return this; } /** * 设置ImageView的bitmap * @param viewId * @param bitmap * @return */ public ViewHolder setImageBitmap(int viewId, Bitmap bitmap){ ImageView view = getView(viewId); view.setImageBitmap(bitmap); return this; } /** * 设置View的点击事件 * @param viewId * @param listener * @return */ public ViewHolder setOnClickListener(int viewId,View.OnClickListener listener){ View view = getView(viewId); view.setOnClickListener(listener); return this; } }
这个就是我们封装好的ViewHolder,比较简单,使用起来还是比较方便的。使用静态方法创建对象。使用共有方法去设置对象,需要传入一个View的id值即可,可以根据项目的需要慢慢增加功能。
3 CommonAdapter的封装
CommonAdapter的封装就比较简单,主要是复写public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)和
public void onBindViewHolder(ViewHolder holder, int position)。其中有一个抽象的方法public abstract void convert(ViewHolder holder,T t,int position);这个主要是把holder与position处的数据做绑定的,这个需要子类来覆写,由子类来实现。
/** * Created by qiyei2015 on 2016/11/30. * 1273482124@qq.com */ public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder> { protected Context mContext; protected List<T> mDatas; protected LayoutInflater mInflater; protected int mLayoutId; public CommonAdapter(Context context,List<T> list,int layoutId){ mContext = context; mDatas = list; mInflater = LayoutInflater.from(mContext); mLayoutId = layoutId; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ViewHolder holder = ViewHolder.createViewHolder(mContext,parent,mLayoutId); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { convert(holder,mDatas.get(position),position); } @Override public int getItemCount() { return mDatas.size(); } /** * 设置数据 * @param data */ public void setData(List<T> data){ mDatas = data; notifyDataSetChanged(); } /** * 根据position返回对应的数据 * @param position * @return */ public T getItem(int position){ return mDatas.get(position); } /** * 子类实现的转换方法 */ public abstract void convert(ViewHolder holder,T t,int position); }
这样子类只需要实现convert(ViewHolder holder,T t,int position)就可以了。比如:
CommonAdapter<String> adapter = new CommonAdapter<String>() { @Override public void convert(ViewHolder holder, String s, int position) { holder.setText(R.id.tv,"hello"); } };
4 多种ItemType类型支持
在项目中,我们经常需要支持多种类型的Item的Adapter,例如今日头条的界面:基本思想就是复写public int getItemViewType(int position),然后根据position处返回特定的type,然后在根据type类型返回响应的布局id,根据布局id生成响应的View,这样就可以实现如上图的效果了。
这里我们引入另外一个接口来支持多种类型的Item。
public interface MultiTypeItem<T> { //根据itemType获取布局文件 int getLayoutId(int itemType); //根据position及T 数据类型 返回对应的ItemType int getItemType(int position,T t); }
支持多种ItemType的Adapter如下:
/** * Created by qiyei2015 on 2016/12/10. * 1273482124@qq.com */ public abstract class MultiAdapter<T> extends CommonAdapter<T> { protected MultiTypeItem<T> mMultiItemType; public MultiAdapter(Context context, List<T> datas, MultiTypeItem<T> itemType){ super(context,datas,-1); mMultiItemType = itemType; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { int id = mMultiItemType.getLayoutId(viewType); return ViewHolder.createViewHolder(mContext,parent,id); } @Override public void onBindViewHolder(ViewHolder holder, int position) { super.onBindViewHolder(holder, position); } /** * 返回position 对应的type * @param position * @return */ @Override public int getItemViewType(int position) { return mMultiItemType.getItemType(position,getItem(position)); } }
使用也很简单,首先新建一个MultiTypeItem对象。然后新建MultiAdapter实例即可。
相关文章推荐
- RecyclerView Adapter简单封装
- RecyclerView 上拉加载的简单封装
- Recyclerview的一些个人理解与使用(一)adapter的简单封装
- 擦!RecyclerView的适配器确实比listview的简单些,因为tag都做了封装了
- RecyclerViewAdapter的简单封装
- 简单封装RecyclerView的Adapter
- 对RecyclerView的封装,使用简单,功能丰富
- RecyclerView适配器的简单封装-BaseAdapter
- RecyclerView的适配器简单封装,再也不用重复写适配器了
- Materialdesign-recyclerview简单封装
- Android中RecyclerView的适配器的简单封装
- 对recyclerview的简单封装
- RecyclerView 使用的简单封装
- RecyclerView.Adapter 的简单封装
- RecyclerView 的简单使用
- RecyclerView介绍(一)----简单概述
- RecyclerView的简单使用
- 简单封装按钮-调整内部label和imageView的相对位置
- 实现对UIAlertController和UIAlertView判断系统后的简单封装
- Android新特性之RecyclerView的简单使用