封装RecyclerView Adapter 实现可添加多个header和footer,可设置loadingView,低耦合的多种布局。
来源:互联网 发布:近几年大学生就业数据 编辑:程序博客网 时间:2024/05/17 02:57
开篇先放代码:戳我下载代码
多种布局的recyclerview的普通写法是重写RecyclerView.Adapter的getItemViewType返回不同position上的type,在onCreateViewHolder(ViewGroup parent,int viewType)里根据不同的type创建不同的viewholder,之后在onBindViewHolder(RecyclerView.ViewHolder holder, int position)里根据不同的viewholder进行数据绑定。但是这种写法具有高度耦合性,每添加一种布局都要在adapter的三个方法做修改。
改进方法
首先封装一个BaseViewHolder:
public abstract class BaseViewHolder<T> extends RecyclerView.ViewHolder { View mItemView; //缓存View SparseArray<View> mViews; public BaseViewHolder(View itemView) { super(itemView); mItemView = itemView; mViews = new SparseArray<>(); } public View getView(int resId) { View view = mViews.get(resId); if (view == null) { view = mItemView.findViewById(resId); mViews.put(resId, view); } return view; } public void setVisibility(int resId, boolean visible) { View view = getView(resId); if (view != null) { view.setVisibility(visible ? View.VISIBLE : View.GONE); } } public abstract void bindData(T data);}
使用SparseArray缓存View,避免每次都调用findViewById。
然后创建一个接口,里面包含根据不同bean返回不同type类型的方法,和创建ViewHolder的方法:
public interface TypeFactory { BaseViewHolder createViewHolder(int type, View itemView); int type(ChannelEntity channelEntity); int type(EntityTwo entityTwo);}
然后创建TypeFactory的实现类实现上述方法,其中type方法返回对应的布局id,因为id不可重复,这样就可以利用id值作为不同布局类型的type值:
public class ItemTypeFactory implements TypeFactory{ @Override public BaseViewHolder createViewHolder(int type, View itemView) { switch (type){ case R.layout.item_my: return new ViewHolderOne(itemView); case R.layout.item_other: return new ViewHolderTwo(itemView); } return null; } @Override public int type(ChannelEntity channelEntity) { return R.layout.item_my; } @Override public int type(EntityTwo entityTwo) { return R.layout.item_other; }}
接下来创建实体bean类的抽象基类,包含一个抽象方法
public abstract class BaseModel { public abstract int type(TypeFactory typeFactory) ;}
创建不同的实体类
public class ChannelEntity extends BaseModel { int id; String name; String letter; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLetter() { return letter; } public void setLetter(String letter) { this.letter = letter; } @Override public int type(TypeFactory typeFactory) { return typeFactory.type(this); }}
最后是BaseRecyclerAdapter,里面包含一个ItemTypeFactory实例,然后在getItemViewType(int position)返回mData.get(getRealPosition(position)).type(itemTypeFactory);将不同布局文件id作为type返回:
@Override public int getItemViewType(int position) { return mData.get(getRealPosition(position)).type(itemTypeFactory); }
在onCreateViewHolder(ViewGroup parent, int viewType)里根据getItemViewType方法里返回的不同的布局id来创建对应的ViewHolder
@Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return itemTypeFactory.createViewHolder(viewType, view); } }
最后在onBindViewHolder方法里调用baseviewholder的bindData方法绑定数据。
此外我还在BaseRecyclerAdapter里实现了添加头尾布局及列表底部的loading布局的方法,以及在更新数据时利用DiffUtil对新旧数据集比较,防止调用notifyDataSetChanged来更新整个recyclerView。具体请看我的github上的代码:
戳我下载代码
- 封装RecyclerView Adapter 实现可添加多个header和footer,可设置loadingView,低耦合的多种布局。
- 一个精简的实现RecyclerView可添加header和footer的Demo
- recyclerView通用适配器,支持添加多个header和footer
- RecyclerView添加Header和Footer的基本原理
- RecyclerView添加Header和Footer的方法
- RecyclerView优雅的添加Header和Footer
- RecyclerView添加Header和Footer
- RecyclerView添加Header和Footer
- RecyclerView添加Header和Footer
- RecyclerView添加header和footer
- RecyclerView添加header和footer
- RecyclerView 添加 Header 和 Footer
- RecyclerView添加Header和Footer
- 从头开始学 RecyclerView(四) 类ListView添加header和footer、多种ViewHolder的支持
- 自定义瀑布流(可添加自定义header和footer)
- 可添加Header可下拉刷新的RecyclerView
- RecyclerView的使用(3)之添加Header和Footer
- RecyclerView的使用(3)之添加Header和Footer
- UVA 10047 The Monocycle(BFS)
- Spring复习(一)
- 机器学习实践系列之2 - GPUImage
- TCP和UDP的区别
- RecycleView的使用以及一些注意点
- 封装RecyclerView Adapter 实现可添加多个header和footer,可设置loadingView,低耦合的多种布局。
- 负数的二进制表示方法
- 【BZOJ】4625 [BeiJing2016]水晶
- glTexParameter
- python生成指定长度的英文数字组合
- Java.给Linux安装JDK和Eclipse
- 2017/2/6笔记
- linux下的信号量
- 搭建django环境(python3.6+django1.10.3)