優雅的給RecyclerView新增頭、腳、上拉載入、下拉重新整理
這裡寫連結內容
- **給RcyclerView新增頭和腳**
- **給RcyclerView新增下拉重新整理**
- **給RcyclerView新增上拉載入**
先上兩張效果圖,如下
給recyclerview新增頭和腳,主要參考的是鴻洋的部落格Android 優雅的為RecyclerView新增HeaderView和FooterView。它的實現原理是在重寫RecyclerView.Adapter的時候,在外層巢狀一個baseAdapter,所有新增頭和腳的程式碼都是在這個baseAdapter中實現的。
其中關於RecyclerView巢狀主要的一個方法就是getType(),根據不同的型別顯示不同的樣式,從而顯示頭和腳,其實頭和腳都只是item的一種而已,相關程式碼如下:
@Override
public int getItemViewType(int position) {
if(isHeader(position)){
return mHeaderViews.keyAt(position); //檢視指定位置的鍵
}else if(isFooter(position)){
return mFooterViews.keyAt(position-getHeaderCount()-getRealItemCount());
}else if(isPullToLoading(position)){
return BASE_PULL_TO_LOADING;
}
return adapter.getItemViewType(position-getHeaderCount());
}
頭和腳的新增方法都還是比較簡單。給recyclerView新增下拉重新整理就完全可以用系統提供的下拉重新整理功能,即SwipeRefreshLayout,SwipeRefreshLayout的用法比較簡單,你只需要把它看成是一個Layout就可以,把你需要重新整理的控制元件,如recyclerView新增到佈局下就可以了,然後在程式碼中進行簡單的設定就可以。
相關程式碼如下:
//給recyclerView新增下拉重新整理(重新整理的顏色可自定義)
layout_swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//更改資料
data.add(0,"下拉重新整理新增的資料");
//這裡的1是新增的頭的個數,因為呼叫系統的重新整理動畫需要傳一個位置引數
helper.notifyItemInserted(1); //重新整理動畫
//關閉下拉重新整理動畫
layout_swipe_refresh.setRefreshing(false);
}
});
當完成了以上功能後,就剩下上拉載入了,這裡我用 到了recyclerView的滑動監聽來實現。具體就是判斷當recyclerview滑動到底部的時候,顯示上拉載入動畫,當資料發生改變後關閉上拉重新整理動畫,當然,這裡的重新整理動畫也是一item,所以,想要更改重新整理樣式,只需要修改item.xml檔案即可,相關程式碼如下:
public abstract class PullToLoading extends RecyclerView.OnScrollListener {
private int beforeCount = 0;
private boolean loading = true; //第一重新整理的時候用
RecyclerView recyclerView;
// 封裝自動重新整理的程式碼
// private Handler handler = new Handler(){
// @Override
// public void handleMessage(Message msg) {
// if(msg.what==1){
// //判斷當顯示了下拉重新整理才關閉重新整理
// if( ((RecyclerViewHelper) recyclerView.getAdapter()).getPullToLoading()==1){
//// ((RecyclerViewHelper) recyclerView.getAdapter()).closePullToLoading();
// }
// }
// }
// };
// boolean isLoading = true;
// public PullToLoading() {
// new Thread(new Runnable() {
// @Override
// public void run() {
// while (true) {
// if (recyclerView != null) {
// int total = recyclerView.getLayoutManager().getItemCount();
// if (loading) {
// loading = false;
// beforeCount = total;
// }
// if (beforeCount < total&&isLoading) {
// LogUtil.showLog("11111111111111111111111111");
// //發訊息
// handler.sendEmptyMessage(1);
// beforeCount = total;
// }
// }
// }
// }
// }).start();
// }
/**
* SCROLL_STATE_TOUCH_SCROLL#手接觸ScrollView觸發一次
* SCROLL_STATE_DRAGGING#正在滾動
* SCROLL_STATE_IDLE#滑動停止
* @param recyclerView
* @param newState
*/
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//已經加載出來的item數量
switch (newState) {
case RecyclerView.TOUCH_SLOP_DEFAULT: //當按下螢幕的時候呼叫
break;
case RecyclerView.TOUCH_SLOP_PAGING: //當快速滑動的時候呼叫
break;
}
// int currentItem = recyclerView.getChildCount(); //載入的item的數量
}
private int findMax(int[] lastPositions) {
int max = lastPositions[0];
for (int value : lastPositions) {
if (value > max) {
max = value;
}
}
return max;
}
//每次滑動的時候呼叫,多次觸發
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
this.recyclerView = recyclerView;
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
int total = recyclerView.getLayoutManager().getItemCount(); //item的總數
int lastPosition = -1;
if (manager instanceof LinearLayoutManager) {
lastPosition = ((LinearLayoutManager) manager).findLastCompletelyVisibleItemPosition();
} else if (manager instanceof GridLayoutManager) {
lastPosition = ((GridLayoutManager) manager).findLastCompletelyVisibleItemPosition();
} else if (manager instanceof StaggeredGridLayoutManager) {
int[] lastPs = new int[((StaggeredGridLayoutManager) manager).getSpanCount()];
((StaggeredGridLayoutManager) manager).findLastVisibleItemPositions(lastPs);
lastPosition = findMax(lastPs);
}
if (lastPosition == total - 1 && (recyclerView.getChildCount() != total)) { //當最後一個位置等於總的item的個數的時候
Log.i("TAG","已經到達底部");
((RecyclerViewHelper) recyclerView.getAdapter()).showPullToLoading();
loading(recyclerView);
//判斷資料發生改變
}
}
/**
* 滑動到底部呼叫
*/
public abstract void loading(RecyclerView recyclerView);
}
recyclerView除了可以實現listview的基本可以功能外,它還可以寫成類似ExampleListView的樣式,具體的程式碼,它的實現效果比傳統的ExampleListView更加好看,更加優雅,可以參見ExpandableRecyclerView ,