RecyclerView的Adapter的多item布局,最常見的是仿照ListView的實(shí)現(xiàn)方式灯节。
其一:
-重寫getItemViewType()方法,根據(jù)需求規(guī)則給出不同的type值绵估。
-在onCreateViewHolder()方法里面根據(jù)不同的type來創(chuàng)建不同的ViewHolder
-在onBindViewHolder()里面根據(jù)不同holder的類型來賦予相對(duì)于的數(shù)據(jù)
如果有額外布局(如:頭部尾部)需要修改getItemCount()方法的返回?cái)?shù)量
更優(yōu)雅的方式:
時(shí)間多的話去看一下 Hannes Dorfmann 大神關(guān)于多布局的故事
本文主要記錄學(xué)習(xí)這種方式的過程炎疆。更優(yōu)雅和解耦。
首先總結(jié)一下不同的item的異同點(diǎn):
- 不同的的布局
- 不同的控件
- 相同的item點(diǎn)擊事件
- 相同的控件賦值操作
針對(duì)第三第四點(diǎn)国裳,我們上一篇的點(diǎn)擊事件和ViewHolder可以復(fù)用形入,不用從新編寫,那就開始吧:
像RecycleView一樣解耦躏救,遵從單一職責(zé)原則唯笙,每個(gè)布局有每個(gè)單元控制,編寫接口:
public interface ItemViewDelegate<T> { int getItemViewLayoutId(); boolean isThisViewType(T item, int position); void convert(RecyclerViewHolder holder, T t, int position); }
ItemViewDelegateManager:多布局控制器盒使,主要功能ViewHolder是加入布局生成ViewHolder
//存儲(chǔ)不同布局單元 SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat(); //添加不同布局單元 public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate){ int viewType = delegates.size(); if (delegate == null) { throw new NullPointerException("ItemViewDelegate is null"); } else { delegates.put(viewType, delegate); } return this;} //getItemViewType public int getItemViewType(T item, int position){ int delegatesCount = delegates.size(); for (int i = delegatesCount - 1; i >= 0; i--) { ItemViewDelegate<T> delegate = delegates.valueAt(i); if (delegate.isThisViewType(item, position)) { return delegates.keyAt(i); } } throw new IllegalArgumentException( "No ItemViewDelegate added that matches position=" + position + " in data source");}
滿足第一和第二點(diǎn)崩掘。不同布局,不同的控件少办。然后編寫MultiItemTypeAdapter苞慢,和封裝的第一個(gè)adapter大同小異:
public class MultiItemTypeAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder>
{
protected Context mContext;
protected List<T> mDatas;
protected ItemViewDelegateManager mItemViewDelegateManager;
public MultiItemTypeAdapter(Context context, List<T> 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<T> itemViewDelegate) {
mItemViewDelegateManager.addDelegate(itemViewDelegate);
return this;
}
@Override
public int getItemCount()
{
return mDatas.size();
}}
使用:
public class MoreItemAdapter extends MultiItemTypeAdapter<String>
{
public MoreItemAdapter(Context context, List<String> datas)
{
super(context, datas);
addItemViewDelegate(new LeftItemDelagate());
addItemViewDelegate(new RightItemDelagate());
}
}