天天看点

RecyclerView优雅的添加Header和Footer

博客转移到个人站点:

http://www.wangchengmeng.club/2018/02/04/RecyclerView%E4%BC%98%E9%9B%85%E7%9A%84%E6%B7%BB%E5%8A%A0Header%E5%92%8CFooter/

欢迎来吐槽

装饰模式:再现有类的基础上,对它进行包装从而对功能对增强。这里简单实现对RecyclerView的Adapter进行装饰,从而简单实现对RecylerView增加Header和Footer。

核心思想也是利用getItemViewType()方法,可以返回多种不同类型的View。

不影响原有的功能,使使用起来跟原生的Adapter方式一样,新建一个WrapperAdapter,继承自RecyclerView.Adapter<RecyclerView.ViewHolder>

1.声明一个枚举:包含三种类型

private enum ITEM_TYPE {

        HEADER, //头部

        FOOTER, //尾部

        NORMAL//正文

    }

2.构造函数,将使用的adapter作为参数传递进来:

    public WrapperAdapter(RecyclerView.Adapter adapter) {

        mAdapter = adapter;

    }

3.添加-删除Header和Footer的方法

    public void addFooter(View footerView) {

        mFooterView = footerView;

        notifyDataSetChanged();

    }

    public void removeFooter() {

        if (hasFooter()) {

            mFooterView = null;

            notifyDataSetChanged();

        }

    }

    public void addHeader(View headerView) {

        mHeaderView = headerView;

    }

    private boolean hasHeader() {

        return null != mHeaderView;

    }

    private boolean hasFooter() {

        return null != mFooterView;

    }

4.getItemViewType方法:

@Override

    public int getItemViewType(int position) {

        int count = mAdapter.getItemCount();//获取除 中间部分的数据条数

        if (hasHeader()) {

            count++; //如果带了header 那就+1

        }

        if (hasHeader() && position == 0) {

            return ITEM_TYPE.HEADER.ordinal(); //返回header类型

        } else if (hasFooter() && position == count) {

            return ITEM_TYPE.FOOTER.ordinal(); //返回footer类型

        } else {

            return ITEM_TYPE.NORMAL.ordinal(); //返回normal类型

        }

    }

5.获取数据的数量:

@Override

    public int getItemCount() {

        int count = mAdapter.getItemCount();

        if (hasHeader()) {

            count++;

        }

        if (hasFooter()) {

            count++;

        }

        return count; //获取数据的数目,要加上对应的带header和footer的条数

    }

6.返回ViewHolder:

@Override

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //根绝不同的类型处理对应的ViewHolder

        if (viewType == ITEM_TYPE.HEADER.ordinal()) {

            return new RecyclerView.ViewHolder(mHeaderView) {

            };

        } else if (viewType == ITEM_TYPE.FOOTER.ordinal()) {

            return new RecyclerView.ViewHolder(mFooterView) {

            };

        } else {

            return mAdapter.onCreateViewHolder(parent, viewType);

        }

    }

7.数据处理的逻辑:

@Override

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if (hasHeader() && position == 0) {

            //header的逻辑分离开来,在外部处理

            return;

        }

        int count = mAdapter.getItemCount();

        if (hasHeader()) {

            count++;

        }

        if (hasFooter()) {

            count++;

        }

        if (hasFooter() && position == count - 1) {

            //footer的逻辑分离开来,在外部处理

            return;

        }

        //normal的逻辑还是不变,跟原生的一样处理,在传递进来的adapter中

        if (hasHeader()) {

            mAdapter.onBindViewHolder(holder, position - 1);

        } else {

            mAdapter.onBindViewHolder(holder, position);

        }

    }

一个简单的添加header和footer就这样装饰出来了,对一个现有的类对它进行一个功能争强,可以利用持有它的引用,原来的操作不变的基础上添加对应的功能。

继续阅读