RecyclerView系列(10)—自定義Adapter(添加HeaderView)

0.前言


上一篇學瞭如何對adapter進行基本的自定義:
https://blog.csdn.net/user11223344abc/article/details/81708502

這篇我們來看看如何爲adapter多封裝一個添加header的方法.

1.代碼


ViewHolder


    package android.zj.com.rcvheaderdemo;

    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.util.SparseArray;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;

    /**
     * ViewHolder
     */
    public class ViewHolder extends RecyclerView.ViewHolder {

        private SparseArray<View> mViews;
        private View mConvertView;

        /**
         * 0.VuewHolder構造函數
         * @param context
         * @param itemview
         * @param parent
         */
        public ViewHolder(Context context, View itemview, ViewGroup parent) {
            super(itemview);
            mConvertView = itemview;
            mViews = new SparseArray<View>();
        }

        /**
         * 1.渲染條目,並創建viewholder,這個方法一般在onCreateViewHolder內進行調用
         * @param context
         * @param parent
         * @param layoutid
         * @return
         */
        public static ViewHolder getHolderById(Context context, ViewGroup parent, int layoutid) {
            View itemview = LayoutInflater.from(context).inflate(layoutid, parent, false);
            ViewHolder holder = new ViewHolder(context, itemview, parent);
            return holder;
        }

        public static ViewHolder getHolderByView(Context context, ViewGroup parent, View view) {
            ViewHolder holder = new ViewHolder(context, view, parent);
            return holder;
        }

        /**
         * 2.擴展方法,根據ViewId獲取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);
                mViews.put(viewid, view);
            }
            return (T) view;
        }
    }

Adapter


package android.zj.com.rcvheaderdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;

import java.util.ArrayList;
import java.util.List;

public abstract class MyAdapter<T> extends RecyclerView.Adapter<ViewHolder> {

    private Context mContext;
    private int mLayoutid;
    private List<T> mDatas;
    private AdapterView.OnItemClickListener monItemClickListener = null;
    private int ITEM_TYPE_HEADER = 1;
    private int ITEM_TYPE_NORMAL = 0;

    /**
     * headerview容器
     */
    private List<View> mHeaderViews = new ArrayList<>();

    /**
     * 添加header
     * @param header
     */
    public void addHeaderView(View header){
        mHeaderViews.add(header);
        notifyDataSetChanged();
    }

    /**
     * adapter構造函數
     * @param mContext
     * @param mLayoutid
     * @param mDatas
     */
    public MyAdapter(Context mContext, int mLayoutid, List<T> mDatas) {
        this.mContext = mContext;
        this.mLayoutid = mLayoutid;
        this.mDatas = mDatas;
    }

    @Override
    public int getItemViewType(int position)
    {
        if(position < mHeaderViews.size()){
            return ITEM_TYPE_HEADER;
        }

        return ITEM_TYPE_NORMAL;
    }

    /**
     * onCreateViewHolder  --> inflate操作  根據 ItemViewType 渲染不同的佈局
     **/
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        ViewHolder viewHolder = null;

        if (viewType == ITEM_TYPE_HEADER) {
            viewHolder = ViewHolder.getHolderByView(mContext, parent, mHeaderViews.get(mHeaderViews.size()-1));
        } else {
            viewHolder = ViewHolder.getHolderById(mContext, parent, mLayoutid);
        }

        return viewHolder;
    }

    /**
     * 暴露出來的接口
     * @param holder
     * @param position
     */
    public abstract void convert(ViewHolder holder, T position);

    /**
     * 擺放
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        if(position < mHeaderViews.size()){
            return;
        }

        convert(holder, mDatas.get(position));
    }

    /**
     * 獲取高度
     *
     * @return
     */
    @Override
    public int getItemCount() {
        if (mDatas == null) {
            return 0;
        }
        return mDatas.size();
    }

}

2.重點分析


判斷是否是header或者footer的條件

這個是根據角標來判斷的。

    @Override
    public int getItemViewType(int position)
    {
        if(position < mHeaderViews.size()){
            return ITEM_TYPE_HEADER;
        }

        return ITEM_TYPE_NORMAL;
    }

onCreateViewHolder根據不同的條件進行不同的渲染,其中就包含header


    /**
     * onCreateViewHolder  --> inflate操作  根據 ItemViewType 渲染不同的佈局
     **/
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        ViewHolder viewHolder = null;

        if (viewType == ITEM_TYPE_HEADER) {
            viewHolder = ViewHolder.getHolderByView(mContext, parent, mHeaderViews.get(mHeaderViews.size()-1));
        } else {
            viewHolder = ViewHolder.getHolderById(mContext, parent, mLayoutid);
        }

        return viewHolder;
    }

onBindViewHolder根據不同的條件進行不同的佈局處理,監測到是header,則不必做過多處理


   /**
     * 擺放
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        if(position < mHeaderViews.size()){
            return;
        }

        convert(holder, mDatas.get(position));
    }

Demo

https://github.com/zj614android/recyclerHeaderAdapter

3.Thanks

基本方法1:https://blog.csdn.net/qibin0506/article/details/49716795
基本方法2:https://blog.csdn.net/qq_38228254/article/details/78374348
添加header方法:https://blog.csdn.net/qibin0506/article/details/49716795
rc設計思想:https://www.jianshu.com/p/9ddfdffee5d3
SparseArray與SparseArrayCompat區別:https://blog.csdn.net/androidiscoding/article/details/79201682

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章