version:2.8.5
更多分享請看:http://cherylgood.cn
又是美好的第一天硕噩,今天我們來學(xué)習(xí)下有關(guān)自動(dòng)加載更多以及預(yù)加載相關(guān)的代碼版仔。
首先我們今天的切入點(diǎn)是:autoLoadMore(int position) 見名知意孙援,是與自動(dòng)加載更多相關(guān)的蠢熄。我們先看下該函數(shù)的代碼實(shí)現(xiàn)
private void autoLoadMore(int position) {
//只有開啟了上拉加載且loadMoreView沒有g(shù)one且data.size>0 時(shí)返回1
if (getLoadMoreViewCount() == 0) {
return;
}
if (position < getItemCount() - mAutoLoadMoreSize) {
return;
}
if (mLoadMoreView.getLoadMoreStatus() != LoadMoreView.STATUS_DEFAULT) {
return;
}
mLoadMoreView.setLoadMoreStatus(LoadMoreView.STATUS_LOADING);
if (!mLoading) {
mLoading = true;
mRequestLoadMoreListener.onLoadMoreRequested();
}
}
第一句先判斷getLoadMoreViewCount判斷是否==0.其實(shí)他并不是簡單的判斷是是否有加載更多視圖的數(shù)量平窘。進(jìn)入方法里:
*/
public int getLoadMoreViewCount() {
if (mRequestLoadMoreListener == null || !mLoadMoreEnable) {
return 0;
}
if (!mNextLoadEnable && mLoadMoreView.isLoadEndMoreGone()) {
return 0;
}
if (mData.size() == 0) {
return 0;
}
return 1;
}
我們可以看到,他的返回結(jié)果跟很多因素有關(guān)跌榔,從代碼很容易看出:
return 0的情況:
1异雁、你沒有設(shè)置mRequestLoadMoreListener 或者沒有開啟mLoadMoreEnable開關(guān);
2僧须、mNextLoadEnable = false 纲刀,mNextLoadEnable 在加載更多結(jié)束時(shí),你調(diào)用
loadMoreEnd(boolean gone) 時(shí)會(huì)置為false担平。且?mLoadMoreView 是處于gone狀態(tài)的示绊。
3锭部、當(dāng)數(shù)據(jù)源大小為0時(shí)
接下來 autoLoadMore方法中的第二句代碼很重要,
if (position < getItemCount() - mAutoLoadMoreSize) {
return;
}
理解起來大概是這樣的面褐,mAutoLoadMoreSize是標(biāo)識開啟自動(dòng)加載更多的一個(gè)數(shù)量閥值拌禾。這個(gè)返回很巧妙。
假設(shè)你的data.size =20 ,mAutoLoadMoreSize =10展哭,當(dāng)前position=9, 按照理解湃窍,這個(gè)pisition=9是個(gè)臨界值,因?yàn)槲覀冊O(shè)置了剩余數(shù)量<10個(gè)時(shí)自動(dòng)加載更多匪傍,此時(shí)計(jì)算9<20-10您市,position等于9,說明后面還有10個(gè)數(shù)據(jù)沒渲染析恢,當(dāng)position=10時(shí)(未加載數(shù)據(jù)還剩9個(gè)墨坚,此時(shí)應(yīng)該預(yù)加載更多),10<20-10映挂,不成立泽篮,代碼繼續(xù)往下走,
執(zhí)行
if (mLoadMoreView.getLoadMoreStatus() != LoadMoreView.STATUS_DEFAULT) {
return;
}
我們?yōu)槭裁催€要做這個(gè)判斷的柑船。假如不做這個(gè)判斷帽撑。直接執(zhí)行下面的代碼。
mLoadMoreView.setLoadMoreStatus(LoadMoreView.STATUS_LOADING);
if (!mLoading) {
mLoading = true;
mRequestLoadMoreListener.onLoadMoreRequested();
}
那么會(huì)出現(xiàn)很好玩的 現(xiàn)象鞍时,當(dāng)你快速上滑時(shí)亏拉,由于position>=10后滿足條件,執(zhí)行加載更多的回調(diào)逆巍,position=11時(shí)也會(huì)執(zhí)行及塘,以此類推,那么你將收到多次加載更多的回調(diào)锐极。所以我們需要判斷此時(shí)是否當(dāng)前的加載更能多回調(diào)已完成笙僚,保證每次到達(dá)閥值后只調(diào)用一次加載更多回調(diào)方法。
理解了這個(gè)方法之后灵再,我們接下來看下該方法在哪里被調(diào)用呢肋层?
@Override
public int getItemViewType(int position) {
if (getEmptyViewCount() == 1) {
//
boolean header = mHeadAndEmptyEnable && getHeaderLayoutCount() != 0;
switch (position) {
case 0:
if (header) {
return HEADER_VIEW;
} else {
return EMPTY_VIEW;
}
case 1:
if (header) {
return EMPTY_VIEW;
} else {
return FOOTER_VIEW;
}
case 2:
return FOOTER_VIEW;
default:
return EMPTY_VIEW;
}
}
autoLoadMore(position);
int numHeaders = getHeaderLayoutCount();
if (position < numHeaders) {
return HEADER_VIEW;
} else {
int adjPosition = position - numHeaders;
int adapterCount = mData.size();
if (adjPosition < adapterCount) {
return getDefItemViewType(adjPosition);
} else {
adjPosition = adjPosition - adapterCount;
int numFooters = getFooterLayoutCount();
if (adjPosition < numFooters) {
return FOOTER_VIEW;
} else {
return LOADING_VIEW;
}
}
}
}
在?getItemViewType方法中,為什么在這個(gè)方法里面呢翎迁,因?yàn)楦鶕?jù)recyclerView.Adapter的執(zhí)行邏輯栋猖,在渲染一個(gè)新的itemview時(shí),會(huì)先調(diào)用getItemViewType詢問我需要加載什么類型的ViewHolder汪榔。在這里調(diào)用能更早的調(diào)用我們的加載更多的方法蒲拉,當(dāng)前,你在onBindViewHolder數(shù)據(jù)綁定方法中調(diào)用也可以實(shí)現(xiàn)這個(gè)功能。接下來就很好理解了全陨,當(dāng)RecyclerView在渲染一個(gè)新的itemView時(shí)爆班,就會(huì)調(diào)用下
autoLoadMore(position);判斷是不是需要調(diào)用加載更多回調(diào)衷掷,需要就調(diào)用辱姨,有關(guān)預(yù)加載的分析就OK啦,我們把加載更多的其他分析放到下一篇中進(jìn)行分析戚嗅。