RecyclerView with Header&Footer (只是记录,没有详细步骤)

RecyclerView with Header&Footer (只是记录,没有详细步骤)

相关知识点

  1. RecyclerView
  2. ListView的头部添加和删除
  3. RecyclerView和ListView的区别

核心内容

  1. FixedViewInfo:A class that represents a fixed view in a list, for example a header at the top or a footer at the bottom.
  2. 因为Recyclerview是ListView的替代品,所以他们之间应该会很接近,但是RecyclerView已经高度解耦了,所以RecyclerView并没有提供添加HeaderView和FooterView的方法,那我们如何为RecyclerView添加自己的Header和Footer呢,当然是重写喽
  3. RecyclerView的适配器数据和布局加载是分开的,哪有如何处理呢。

源码分析

  1. 因为RecyclerView都是简介或者直接继承了ViewGroup跟ListView没有半毛钱关系,所以我们就不看他们的构造函数了。
  2. 我们直接看他添加添加头部和尾部的方法吧:addHeaderView/addFooterView

` 
public void addFooterView(View v, Object data, boolean isSelectable) {
    final FixedViewInfo info = new FixedViewInfo();
    info.view = v;
    info.data = data;
    info.isSelectable = isSelectable;
    mFooterViewInfos.add(info);
    mAreAllItemsSelectable &= isSelectable;

    // Wrap the adapter if it wasn't already wrapped.
    if (mAdapter != null) {
        if (!(mAdapter instanceof HeaderViewListAdapter)) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
        }

        // In the case of re-adding a footer view, or adding one later on,
        // we need to notify the observer.
        if (mDataSetObserver != null) {
            mDataSetObserver.onChanged();
        }
    }
}

`


`
public void addFooterView(View v, Object data, boolean isSelectable) {
    final FixedViewInfo info = new FixedViewInfo();
    info.view = v;
    info.data = data;
    info.isSelectable = isSelectable;
    mFooterViewInfos.add(info);
    mAreAllItemsSelectable &= isSelectable;

    // Wrap the adapter if it wasn't already wrapped.
    if (mAdapter != null) {
        if (!(mAdapter instanceof HeaderViewListAdapter)) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
        }

        // In the case of re-adding a footer view, or adding one later on,
        // we need to notify the observer.
        if (mDataSetObserver != null) {
            mDataSetObserver.onChanged();
        }
    }
}`

3、他的精妙指出是在addHeaderView和AddFooterView中用代理的方式,将当前的adapter和头部和底部的列表整合在了一起,所以我们的思路就是仿照ListView的这种做法,自己编写代理adapter,同时在addFooterView和AddFooterView方法中调用和使用,同时这里不要漏掉一个细节,解释listview的setAdapter方法也需要使用这种代理adapter,这样提高代码的重用,所以代理adapter里面要分别处理头部和底部以及中间内容数据。来看看ListView的代理适配器对视图加载和数据填充的getView方法吧:


 在ListView中的处理
     public View getView(int position, View convertView, ViewGroup parent) {
    // Header (negative positions will throw an IndexOutOfBoundsException)
    int numHeaders = getHeadersCount();
    if (position < numHeaders) {
        return mHeaderViewInfos.get(position).view;
    }

    // Adapter
    final int adjPosition = position - numHeaders;
    int adapterCount = 0;
    if (mAdapter != null) {
        adapterCount = mAdapter.getCount();
        if (adjPosition < adapterCount) {
            return mAdapter.getView(adjPosition, convertView, parent);
        }
    }

    // Footer (off-limits positions will throw an IndexOutOfBoundsException)
    return mFooterViewInfos.get(adjPosition - adapterCount).view;
}

在RecyclerView代理adapter相应的处理
@Override
public void onBindViewHolder(ViewHolder holder, int pos) {
    int numHeaders = getHeadersCount();
    // Header
    if (pos < numHeaders) {
        return;
    }

    // Adapter
    final int adjPosition = pos - numHeaders;
    int adapterCount = 0;
    if (mAdapter != null) {
        adapterCount = mAdapter.getItemCount();
        if (adjPosition < adapterCount) {
            mAdapter.onBindViewHolder(holder, adjPosition);
            return;
        }
    }

    // Footer (off-limits positions will throw an IndexOutOfBoundsException)
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Header
    if (viewType == RecyclerView.INVALID_TYPE) {
        return new HeaderViewHolder(mHeaderViewInfos.get(0));
    } else if (viewType == RecyclerView.INVALID_TYPE - 1) {// Footer
        return new HeaderViewHolder(mFooterViewInfos.get(0));
    }
    // Content
    return mAdapter.onCreateViewHolder(parent, viewType);
}

总结:这只是一个简单的例子如果你懂ListView添加头部和底部的机制,那在RecyclerView中做到同样的功能只是分分钟的事情,只是要注意两者可能调用的方法不同,还有本文只是记录,并非指导开发,如有不详尽之处,勿喷。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值