RecyclerView粘性頭部控制元件
阿新 • • 發佈:2019-01-09
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近使用了一個粘性頭部控制元件sticky-headers-recyclerview,期間也遇到了不少問題,稍微介紹一下這個控制元件的使用和問題。</span>
匯入方法:
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、
和普通的一樣,繫結資料,要注意的是這個position是子項的,因為此控制元件機制是新增分割線addItemDecoration,所以新增頭部後不會影響原位置。@Override public void onBindHeaderViewHolder(ViewHolder holder, int position) { }
在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();
}
});
在滑動的時候,重新整理頭部,就能完全顯示資料了。因為頭部內容其實並不多,所以也不是特別消耗效能。如果大家有更好的方法可以提出來。專案趕得太緊,只能看到啥用啥了。