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就这样装饰出来了,对一个现有的类对它进行一个功能争强,可以利用持有它的引用,原来的操作不变的基础上添加对应的功能。

猜你喜欢

转载自blog.csdn.net/xiaohuanqi/article/details/77247508
今日推荐