<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近使用了一个粘性头部控件sticky-headers-recyclerview,期间也遇到了不少问题,稍微介绍一下这个控件的使用和问题。</span>
Github管理地址:timehop/sticky-headers-recyclerview
导入方法:
compile 'com.timehop.stickyheadersrecyclerview:library:[latest.version.number]@aar'
或者直接引入自己项目,结构如下:
使用方法:
这个控件方便之处在于不用大改原Adapter,加入头部就行了,也不需要用getItemViewType()来判断ITEM类型。
原Adapter需要implements StickyRecyclerHeadersAdapter,然后重写以下方法
1、
@Override
public long getHeaderId(int position) {
return getGroupPosition(position);
}
这个方法是用来固定头部的,有着相同的HeaderId的Item的头部将会是同一个,这个ID可以自己设置
getGroupPosition(position)是自定义的方法,用于根据子ITEM的position来获取服务器返回的List的父项位置。根据这个特性同时用来当HeaderID。
如果有不是数据里的特殊的头部,置顶之类的,可以设置-1之类的。
2、
@Override
public ViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_head_choose, parent, false);
return new HeaderViewHolder(view);
}
这个很明确,加载布局文件就行了。
3、
@Override
public void onBindHeaderViewHolder(ViewHolder holder, int position) {
}
和普通的一样,绑定数据,要注意的是这个position是子项的,因为
此控件机制是添加分割线addItemDecoration,所以添加头部后不会影响原位置。
在Recyclerview中
StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(adapter); //绑定之前的adapter
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
headersDecor.invalidateHeaders();
}
}); //刷新数据的时候回刷新头部
添加头部:
rcv.addItemDecoration(headersDecor);
注意只能添加一次,要更行数据使用
headersDecor.invalidateHeaders();
否则一直会加头部。
如果你的需求只是显示粘性头部,那么到这里已经可以显示了
但是当点击粘性头部的时候,就会有一些问题了。
<span style="white-space:pre"> </span>//头部点击事件
StickyRecyclerHeadersTouchListener touchListener = new StickyRecyclerHeadersTouchListener(rcv, headersDecor);
touchListener.setOnHeaderClickListener(new StickyRecyclerHeadersTouchListener.OnHeaderClickListener() {
@Override
public void onHeaderClick(View header, int position, long headerId) {
//这边的坑在于,在顶上的粘性头部,position和headerId都会是0,这样就无法获取到这个头部的数据了。
//在这里我们要用mLayoutManager.findFirstVisibleItemPosition()来获取到目前顶部子项数据,然后进一步推算出头部的数据
//如果进行了头部数据更新,刷新头部headersDecor.invalidateHeaders();
}
});
rcv.addOnItemTouchListener(touchListener);
还有我的头部因为有小图片的存在,使用的是Glide加载图片,结果发现,图片经常会卡在隐现状态,或者压根没出来,他就这么卡住了。。。
估计是控件本身的bug,后来只能采取取巧的方法
rcv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
headersDecor.invalidateHeaders();
}
});
在滑动的时候,刷新头部,就能完全显示数据了。因为头部内容其实并不多,所以也不是特别消耗性能。如果大家有更好的方法可以提出来。