版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接:https://blog.csdn.net/qijingwang/article/details/79909120
1、肯定問題
首先肯定一下問題究竟是什麼,測試說xrecyclerview(一個github上的三方庫,不知道的能夠去github上找找,有細節上的bug總體來講很好用)的上拉加載更多功能在有的手機上能夠加載更多,有的手機上不能加載更多,這說明這個功能是沒有問題的,由於有手機能夠實現,難道是手機的問題?拿來測試說的不能上拉加載更多的手機,連上adb,查看一下日誌,沒有不少信息,就是onLoadMore()接口方法沒有被調用,打開crecyclerview源碼,找到哪裏調用了這個接口,以下:git
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if (state == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) {
LayoutManager layoutManager = getLayoutManager();
int lastVisibleItemPosition;
if (layoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
lastVisibleItemPosition = findMax(into);
} else {
lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
}
if (layoutManager.getChildCount() > 0
&& lastVisibleItemPosition >= layoutManager.getItemCount() - 1 && layoutManager.getItemCount() > layoutManager.getChildCount() && !isNoMore && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) {
isLoadingData = true;
if (mFootView instanceof LoadingMoreFooter) {
((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_LOADING);
} else {
mFootView.setVisibility(View.VISIBLE);
}
mLoadingListener.onLoadMore();
}
}
}
經過源碼能夠看出來,那個一長串的條件就是影響上拉加載更多接口onLoadMore能不能被調用的關鍵。
那麼如今肯定了影響條件的關鍵,下一步就是想辦法篩選這些條件,看看究竟是誰影響了代碼。github
2、肯定影響條件
由於是使用依賴下載的三方庫,因此並不能直接修改源碼,或者打印斷點調試,從github上下載源碼運行編譯的時間又比較長,因此我選擇了一個比較懶的方法,寫一個TestXRecyclerview繼承xrecyclerview,並重寫onScrollStateChanged(int state)方法,讓他運行我本身的方法,這裏須要注意的是,通常狀況下,仍是用下載源碼打斷點調試的方法比較好,可是這個問題涉及到的類和方法只有一個,因此用了這樣的方式。
具體TestXRecyclerview類代碼以下:app
public class TestXRecyclerView extends XRecyclerView {
public TestXRecyclerView(Context context) {
super(context);
}
public TestXRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TestXRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onScrollStateChanged(int state) {
// super.onScrollStateChanged(state);
if (state == RecyclerView.SCROLL_STATE_IDLE) {
Log.i("log" , "==是否調用加載更多方法1==");
LayoutManager layoutManager = getLayoutManager();
int lastVisibleItemPosition;
if (layoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
lastVisibleItemPosition = 20;
} else {
lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
}
if (layoutManager.getChildCount() > 0
&& lastVisibleItemPosition >= layoutManager.getItemCount() - 1 && layoutManager.getItemCount() > layoutManager.getChildCount()) {
Log.i("log" , "==是否調用加載更多方法2==");
}
}
}
}
首先是把super.onScrollStateChanged(state);方法註釋掉,而後複製源碼裏面的onScrollStateChanged(int state) 方法出來,把一些無關的條件去掉(這裏須要本身判斷是否有關),最終剩下以上代碼,運行,並無調用本身寫的log:方法2,說明layoutManager.getChildCount() > 0 , lastVisibleItemPosition >= layoutManager.getItemCount() - 1 , layoutManager.getItemCount() > layoutManager.getChildCount() 這三個條件中有一個或者幾個返回了false。這裏先看layoutManager.getChildCount() > 0,這個條件確定不是false,由於數據都顯示出來了,那就是剩下的兩個條件,其實到這裏我已經忽然想到了,有多是item的總高度不夠致使上拉加載更多不能觸發,由於咱們分頁機制是一頁返回十條,如今一頁裏面已經顯示了九條多的數據,不一樣手機的高度不同,這就是爲何有的手機能夠有的手機不能夠,不過既然已經到了這裏,仍是要完整的解決問題才行
想解決上面的問題,就要明白layoutManager.getItemCount()和 layoutManager.getChildCount()是什麼意思,順手開始谷歌,感受不對,說好的看源碼呢?因而回去,ctrl點開getChildCount()方法源碼ide
/**
* Return the current number of child views attached to the parent RecyclerView.
* This does not include child views that were temporarily detached and/or scrapped.
*
* @return Number of attached children
*/
public int getChildCount() {
return mChildHelper != null ? mChildHelper.getChildCount() : 0;
}
嗯。。。再點開mChildHelper.getChildCount()測試
int getChildCount() {
return mCallback.getChildCount() - mHiddenViews.size();
}
看英文意思,應該是全部item的數量,減去沒有顯示在頁面上的item的數量,那getChildCount()就是顯示在頁面上的item的數量咯。那不出意外,layoutManager.getItemCount()應該就是全部item的數量,很好,我已經提起興趣了,點開源碼:.net
public int getItemCount() {
final Adapter a = mRecyclerView != null ? mRecyclerView.getAdapter() : null;
return a != null ? a.getItemCount() : 0;
}
猜對啦,如今基本上能明白,lastVisibleItemPosition >= layoutManager.getItemCount() - 1,layoutManager.getItemCount() > layoutManager.getChildCount() ,這兩句話都是同一個意思能看到的item數量,要比全部的item的數量大,否則就不觸發上拉加載更多,想想,分頁返回十條數據,一頁就顯示了九條,在不一樣手機上由於分辨率的不一樣,有的能看到九條,有的能看到十條,找到了緣由所在,問題就很好解決了,給item增長一些高度,或者讓後臺每條數據返回多一些就能夠啦。調試
做者:Zero零夜
連接:https://www.jianshu.com/p/8fe3af6890f2
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
————————————————
版權聲明:本文爲CSDN博主「qijingwang」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/qijingwang/article/details/79909120日誌