RecyclerView的封裝以實現上拉加載更多
下拉加載更多功能是怎么實現的呢?
當實現recyclerview的時候,通常需要實現adapter跟viewholder,首先我們要明白adapter里面各個方法的調用順序。
1. 首先調用getItemCount(),作為recyclerview里的item數量
2. 調用getItemViewType(int position),該方法返回一個int值作為onCreateViewHolder中的viewtype參數
3. 調用onCreateViewHolder(ViewGroup parent, int viewType)
4. 調用onBindViewHolder(BaseViewHolder holder, int position)
recyclerview的設計思路是這樣的,引用網上一張圖:
image
如上,adapter負責把數據傳給viewholder,viewhoder就相當於一個item,recyclerview通過布局策略layout這些item。
adapter與recyclerview是一個觀察者模式,當adpater發生變化通知recyclerview觸發重新布局,這就是我們調用adapter的notify時會發生的改變。
簡單講完recyclerview的原理,接下來就可以開始說說我們的上拉加載更多了。
1.首先我們需要下拉加載更多的進度條,因此當我們當我們返回item數量時要多返回一個item,作為顯示加載更多的item。如下,我們返回data的數量+1的item數。
@Override
public int getItemCount() {
if (mNewsData.size() > 0) {
return mNewsData.size()+1;
}
return 0;
}
1
2
3
4
5
6
7
2.當加載到最后一個數據時,這個item為加載更多的那個item,返回不同的viewtype給onCreateViewHolder
@Override
public int getItemViewType(int position) {
if (position>=mNewsData.size()){
return TYPE_FOOT;
}
return TYPE_NORMAL;
}
1
2
3
4
5
6
7
3.onCreateViewHolder根據不同的viewtype返回不同的布局。
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType==TYPE_FOOT){
View itemView = LayoutInflater.from(mContext).inflate(R.layout.listview_footer, parent, false);
return new BaseViewHolder(itemView, mContext);
}else {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_news, parent, false);
return new BaseViewHolder(itemView, mContext);
}
}
1
2
3
4
5
6
7
8
9
10
到此我們就實現了加載更多的布局,但是我們還需要去加載數據。我們可以封裝recyclerview,當它滑動到數據底部的時候回調接口,觸發下載跟多數據。並notify adapter。
recyclerview中有個onScrollStateChanged(int state)方法,State主要有:
SCROLL_STATE_IDLE表示當前並不處於滑動狀態
SCROLL_STATE_DRAGGING表示當前RecyclerView處於滑動狀態(手指在屏幕上)
SCROLL_STATE_SETTLING表示當前RecyclerView處於滑動狀態,(手已經離開屏幕)。
我們只要判斷當recyclerview沒有在滑動的時候,這時是否已經滑動到了最后一個item。
@Override
public void onScrollStateChanged(int state){
if (state==RecyclerView.SCROLL_STATE_IDLE){
Log.d("LoadMoreRecyclerView","run in onScrollStateChanged");
LayoutManager layoutManager=getLayoutManager();
int lastVisiblePosition;
if (layoutManager instanceof GridLayoutManager){
lastVisiblePosition=((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
}else if (layoutManager instanceof StaggeredGridLayoutManager){
int into[]=new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
((StaggeredGridLayoutManager)layoutManager).findLastVisibleItemPositions(into);
lastVisiblePosition=findMax(into);
}else {
lastVisiblePosition= ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
}
Log.d("LoadMoreRecyclerView","ChildCount: "+layoutManager.getChildCount()+" lastvisiblePosition: "
+lastVisiblePosition+" ItemCount: "+layoutManager.getItemCount());
if (layoutManager.getChildCount()>0 //當當前顯示的item數量>0
&&lastVisiblePosition>=layoutManager.getItemCount()-1 //當當前屏幕最后一個加載項位置>=所有item的數量
&&layoutManager.getItemCount()>layoutManager.getChildCount()) { // 當當前總Item數大於可見Item數
Log.d("LoadMoreRecyclerView","run onLoadMore");
if (mLoadMoreListener!=null){
mLoadMoreListener.onLoadMore();
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
通過回調LoadMoreListener的onLoadMore()我們就可以去加載數據,並通過adapter更新recyclerview了。
---------------------
作者:All_BIue
來源:CSDN
原文:https://blog.csdn.net/allbule/article/details/77279427
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!