給RecyclerView封裝個Adapter吧(更優(yōu)雅的實現(xiàn)多item支持)

RecyclerView的Adapter的多item布局,最常見的是仿照ListView的實現(xiàn)方式。

其一:

-重寫getItemViewType()方法,根據(jù)需求規(guī)則給出不同的type值。
-在onCreateViewHolder()方法里面根據(jù)不同的type來創(chuàng)建不同的ViewHolder
-在onBindViewHolder()里面根據(jù)不同holder的類型來賦予相對于的數(shù)據(jù)
如果有額外布局(如:頭部尾部)需要修改getItemCount()方法的返回數(shù)量

更優(yōu)雅的方式:

時間多的話去看一下 Hannes Dorfmann 大神關(guān)于多布局的故事

本文主要記錄學習這種方式的過程。更優(yōu)雅和解耦。
首先總結(jié)一下不同的item的異同點:

  1. 不同的的布局
  2. 不同的控件
  3. 相同的item點擊事件
  4. 相同的控件賦值操作
    針對第三第四點,我們上一篇的點擊事件和ViewHolder可以復用,不用從新編寫,那就開始吧:
    像RecycleView一樣解耦,遵從單一職責原則,每個布局有每個單元控制,編寫接口:
    public interface ItemViewDelegate<T> { int getItemViewLayoutId(); boolean isThisViewType(T item, int position); void convert(RecyclerViewHolder holder, T t, int position); }
    ItemViewDelegateManager:多布局控制器,主要功能ViewHolder是加入布局生成ViewHolder

//存儲不同布局單元 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");}

滿足第一和第二點。不同布局,不同的控件。然后編寫MultiItemTypeAdapter,和封裝的第一個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());
}
}
Paste_Image.png

傳送門,請切換到develop分支

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容