ListView中有个addHeaderView方法和addFooterView方法,因此观看了ListView的实现原理之后,发现其实也没那么难,下面我们来看看ListView里面addHeader的流程
该方法首先判断传进来的headerView是否在RecyclerView里面的子控件,若不是则抛一个警告,ListView里面有一个mHeaderViewInfos和mFooterViewInfos用于保存HeaderView和FooterView的信息,当添加一个HeaderView时,就会添加到mHeaderViewInfos中
下面的方法把我们传进来的Adapter替换成了一个WraperListAdapter,也就是偷梁换柱啦
贴不上图了,上代码吧。。。
//以上只是将要添加的HeaderView一个列表中并跟Adapter一起被封装成HeaderViewListAdapter,并没有说在哪里显示,因此猜测HeaderViewListAdapter应该会有显示View的方法,因此我想这在ListView的setAdapter中会不会找到线索
@Override
public void setAdapter(ListAdapter adapter) {
//先是确保当前的Adapter是为空的
if (mAdapter != null && mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();//清空ListView中原来的数据
mRecycler.clear();//不知道mRecycler是个什么鬼
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {//HeaderViweInfos或者mFooterViewInfos是否大于0
//若mHeaderViewInfos是大于0的,将Adapter封装成HeaderViewListAdapter
mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {//否则不做任何改变
mAdapter = adapter;
}
mOldSelectedPosition = INVALID_POSITION;//目测是当前被选中的条目,将要进行绑定和显示的,知道有这个东西就行了,其实我也不太懂
mOldSelectedRowId = INVALID_ROW_ID;
// AbsListView#setAdapter will update choice mode states.
super.setAdapter(adapter);
if (mAdapter != null) {
//下面其实就是调用的我们传进来的Adapter的方法,setAdapter其实就是将我们传进来的Adapter做了一层封装
mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
mOldItemCount = mItemCount;
mItemCount = mAdapter.getCount();
checkFocus();
mDataSetObserver = new AdapterDataSetObserver();//创建一个观察者,用于观察adapter中的数据是否发生变化
mAdapter.registerDataSetObserver(mDataSetObserver);
mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());//