RecyclerView粘性头部控件 - sticky-headers-recyclerview

来源:互联网 发布:super java怎么理解 编辑:程序博客网 时间:2024/05/10 06:59

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近使用了一个粘性头部控件sticky-headers-recyclerview,期间也遇到了不少问题,稍微介绍一下这个控件的使用和问题。</span>

animated gif demo


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); //绑定之前的adapteradapter.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();            }        });
在滑动的时候,刷新头部,就能完全显示数据了。因为头部内容其实并不多,所以也不是特别消耗性能。如果大家有更好的方法可以提出来。


项目赶得太紧,只能看到啥用啥了。




3 0
原创粉丝点击