RecyclerView的Adapter的多item布局,最常见的是仿照ListView的实现方式。
其一:
-重写getItemViewType()方法,根据需求规则给出不同的type值。
-在onCreateViewHolder()方法里面根据不同的type来创建不同的ViewHolder
-在onBindViewHolder()里面根据不同holder的类型来赋予相对于的数据
如果有额外布局(如:头部尾部)需要修改getItemCount()方法的返回数量
更优雅的方式:
时间多的话去看一下 Hannes Dorfmann 大神关于多布局的故事
本文主要记录学习这种方式的过程。更优雅和解耦。
首先总结一下不同的item的异同点:
- 不同的的布局
- 不同的控件
- 相同的item点击事件
- 相同的控件赋值操作
针对第三第四点,我们上一篇的点击事件和ViewHolder可以复用,不用从新编写,那就开始吧:
像RecycleView一样解耦,遵从单一职责原则,每个布局有每个单元控制,编写接口:
public interface ItemViewDelegate
{ int getItemViewLayoutId(); boolean isThisViewType(T item, int position); void convert(RecyclerViewHolder holder, T t, int position); }
ItemViewDelegateManager:多布局控制器,主要功能ViewHolder是加入布局生成ViewHolder
//存储不同布局单元 SparseArrayCompat
满足第一和第二点。不同布局,不同的控件。然后编写MultiItemTypeAdapter,和封装的第一个adapter大同小异:
public class MultiItemTypeAdapter extends RecyclerView.Adapter
{
protected Context mContext;
protected List mDatas;
protected ItemViewDelegateManager mItemViewDelegateManager;
public MultiItemTypeAdapter(Context context, List datas)
{
mContext = context;
mDatas = datas;
mItemViewDelegateManager = new ItemViewDelegateManager();
}
@Override
public int getItemViewType(int position)
{
if (mItemViewDelegateManager.getItemViewDelegateCount() <= 0)
return super.getItemViewType(position);
return mItemViewDelegateManager.getItemViewType(mDatas.get(position), position);
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
ItemViewDelegate itemViewDelegate = mItemViewDelegateManager.getItemViewDelegate(viewType);
int layoutId = itemViewDelegate.getItemViewLayoutId();
View itemView = LayoutInflater.from(mContext).inflate(layoutId, parent,
false);
RecyclerViewHolder holder = new RecyclerViewHolder(mContext, itemView);
return holder;
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position)
{
convert(holder, mDatas.get(position));
}
public void convert(RecyclerViewHolder holder, T t)
{
mItemViewDelegateManager.convert(holder, t, holder.getAdapterPosition());
}
public MultiItemTypeAdapter addItemViewDelegate(ItemViewDelegate itemViewDelegate) {
mItemViewDelegateManager.addDelegate(itemViewDelegate);
return this;
}
@Override
public int getItemCount()
{
return mDatas.size();
}}
使用:
public class MoreItemAdapter extends MultiItemTypeAdapter
{
public MoreItemAdapter(Context context, List datas)
{
super(context, datas);
addItemViewDelegate(new LeftItemDelagate());
addItemViewDelegate(new RightItemDelagate());
}
}
传送门,请切换到develop分支