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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在RecyclerViewAdapter添加一个HeaderView,可以使用以下步骤: 1. 创建一个新的布局文件,用于表示HeaderView。 2. 创建一个新的ViewHolder类,用于表示HeaderView,并实现必要的方法。 3. 在Adapter中重写getItemViewType()方法,以便RecyclerView能够区分HeaderView和其他项。 4. 在Adapter中重写onCreateViewHolder()方法,以便根据视图类型创建正确的ViewHolder。 5. 在Adapter中重写onBindViewHolder()方法,以便为HeaderView设置数据。 下面是一个示例Adapter代码,演示如何添加HeaderView: ```java public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int VIEW_TYPE_HEADER = 0; private static final int VIEW_TYPE_ITEM = 1; private List<String> mItems; private View mHeaderView; public MyAdapter(List<String> items, View headerView) { mItems = items; mHeaderView = headerView; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == VIEW_TYPE_HEADER) { return new HeaderViewHolder(mHeaderView); } else { View itemView = inflater.inflate(R.layout.item_layout, parent, false); return new ItemViewHolder(itemView); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (getItemViewType(position) == VIEW_TYPE_ITEM) { ItemViewHolder itemViewHolder = (ItemViewHolder) holder; String item = mItems.get(position - 1); // subtract 1 to account for header itemViewHolder.bind(item); } } @Override public int getItemCount() { return mItems.size() + 1; // add 1 to account for header } @Override public int getItemViewType(int position) { return position == 0 ? VIEW_TYPE_HEADER : VIEW_TYPE_ITEM; } static class HeaderViewHolder extends RecyclerView.ViewHolder { public HeaderViewHolder(View itemView) { super(itemView); } } static class ItemViewHolder extends RecyclerView.ViewHolder { private TextView mTextView; public ItemViewHolder(View itemView) { super(itemView); mTextView = itemView.findViewById(R.id.text_view); } public void bind(String item) { mTextView.setText(item); } } } ``` 在上面的示例中,HeaderView在getItemViewType()方法中被视为第一个项目(position == 0),并在onCreateViewHolder()方法中使用HeaderViewHolder创建。在onBindViewHolder()方法中,我们只需要绑定实际项目,因此需要将位置减去1(position - 1)以跳过HeaderView
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值