Recycleview的推出是用于替代ListView的,它为我们展示数据提供了非常便捷的方式,RecyclerView与ListView原理是类似的:都是维护少量的View并且可以展示大量的数据集。RecyclerView是高度的解耦,非常灵活的,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator,作为老司机的我们可以任意飙车,体验飞般的感觉。
RecyclerView虽然作为ListView的替代者有着较好的性能提升,但是ListView的一些常用功能却没有提供,比如我们平时会经常用到的addHeaderView,addFooterView等方法并没有提供,虽然它没有提供,但有时候我们又需要这样的功能,这可怎么办?那当然是自己造一个了,怎么造?作为小白,自己想破头也想不出什么思路来,眼见要翻车了,机智的小白想到:既然Recycleview是替代ListView出现的,那他们的原理应该类似,那ListView的addHeaderView,addFooterView又是怎么实现的呢?我们能不能依葫芦画瓢仿着Listview写一个呢?先上效果图,看合不合您胃口:
诺,就这个效果,怎么搞,接下来就跟着小白去查看一下Listview的源码吧,去找找里面有什么蛛丝马迹可供我们参考的,首先我们找到ListView源码里面的addHeaderView方法 源码如下:
public void addHeaderView(View v, Object data, boolean isSelectable) {
//FixedViewInfo 是一个数据的封装,用于保存我们添加的头部View和View 相关的数据
final FixedViewInfo info = new FixedViewInfo();
info.view = v;
info.data = data;
info.isSelectable = isSelectable;
//一个ArrayList用于保存添加进来的头部View
mHeaderViewInfos.add(info);
mAreAllItemsSelectable &= isSelectable;
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {
if (!(mAdapter instanceof HeaderViewListAdapter)) {
//如果mAdapter的类型是通用的Adapter就调用包装方法包装该普通的adapter
wrapHeaderListAdapterInternal();
}
//否则调用HeaderAdapter的添加View功能,刷新数据
// In the case of re-adding a header view, or adding one later on,
// we need to notify the observer.
if (mDataSetObserver != null) {
mDataSetObserver.onChanged();
}
}
}
仔细一瞧,小白恍然大悟,长吼一声“原来如此”。FixedViewInfo 是一个数据类的封装,用于保存我们添加进来的头部View和它关联的数据,mHeaderViewInfos是一个ArrayList用于保存添加进来的头部View如果该adapter是HeaderViewListAdapter那么就调wrapHeader
ListAdapterInternal();否则就调用普通的adapter也就是没有头部View的adapter,不做处理。
接下来我们看看wrapHeaderListAdapterInternal具体是怎么实现的:
/** @hide */
protected void wrapHeaderListAdapterInternal() {
mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
传入保存头部和底部ItemView 的mHeaderViewInfos,mFooterViewInfos集合, 调用该方法会给我返回一个特殊的mAdapter;接着往下看,它有什么特殊之处:
/** @hide */
protected HeaderViewListAdapter wrapHeaderListAdapterInternal(
ArrayList<ListView.FixedViewInfo> headerViewInfos,
ArrayList<ListView.FixedViewInfo> footerViewInfos,
ListAdapter adapter) {
return