前言
RecyclerView是support.v7包中的控件,可以說(shuō)是ListView和GridView的增強(qiáng)升級(jí)版。
官方對(duì)RecyclerView的描述是(不翻譯是因?yàn)槲也⒉幌氪蜷_有道詞典,就這樣):
A flexible view for providing a limited window into a large data set.
RecyclerView從2014年發(fā)布到現(xiàn)在已經(jīng)很長(zhǎng)時(shí)間了,使用已經(jīng)相當(dāng)普遍。
初入坑的同學(xué)請(qǐng)自行搜索詳細(xì)教程,樓主這里不再贅述。
入坑
既然要做列表,分頁(yè),下拉刷新上拉加載這些司空見慣的功能當(dāng)然必不可少。下拉刷新樓主選用了SwipeRefreshLayout(真心喜歡!!!)然后上拉加載的時(shí)候樓主用的是RecyclerView的滑動(dòng)監(jiān)聽(什么時(shí)候有個(gè)像SwipeRefreshLayout一樣完美的上拉加載就好了,重任交給你們了)
recyclerView.setOnScrollListener(newRecyclerView.OnScrollListener() {
@Override
public voidonScrollStateChanged(RecyclerView recyclerView,intnewState) {
?????super.onScrollStateChanged(recyclerView, newState);
????switch(newState) {
????????caseRecyclerView.SCROLL_STATE_IDLE:
????????????if(isSlideToBottom(recyclerView)) {
????????????????initData(); //加載接口
????????????}
????}
????break;
}
}
});
判斷是否到底的方法也是樓主借鑒大神比較靠譜的方法(文化人的事不能叫偷)
public static booleanisSlideToBottom(RecyclerView recyclerView) {
if(recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
>= recyclerView.computeVerticalScrollRange()) {
return true;
}else{
return false;
}
}
腳部局添加樓主不在贅述,注意的是recycleView并沒有addFootView(View view)的方法,樓主是在底部隱藏了一個(gè)布局 ,到底顯示再隱藏。
問(wèn)題來(lái)了,當(dāng)一頁(yè)數(shù)據(jù)量過(guò)少不滿一屏?xí)r,加載便出現(xiàn)了問(wèn)題,下拉刷新觸發(fā)了上拉加載并且不是觸發(fā)了一次!這就導(dǎo)致出現(xiàn)的數(shù)據(jù)是隨機(jī)頁(yè)數(shù)上的并無(wú)規(guī)律可言。一開始樓主使用斷點(diǎn)調(diào)試并無(wú)發(fā)現(xiàn)問(wèn)題,神奇之處就在這里,斷點(diǎn)調(diào)試的時(shí)候下拉刷新并未觸發(fā)上拉加載!但是log輸出時(shí)卻能看出下拉刷新觸發(fā)了上拉加載并且不是觸發(fā)了一次!
出坑
? ? 細(xì)細(xì)想來(lái)終于明白,原來(lái)問(wèn)題出在判斷recyclerView是否到底上,原理圖如下,是view自帶的方法
這樣就很清晰明了,computeVerticalScrollExtent()是當(dāng)前屏幕顯示的區(qū)域高度,computeVerticalScrollOffset() 是當(dāng)前屏幕之前滑過(guò)的距離,而computeVerticalScrollRange()是整個(gè)View控件的高度。
條目不滿一屏,控件是到底的(其實(shí)很簡(jiǎn)單的一個(gè)道理,牛角尖里的人被蒙蔽了雙眼)這也就導(dǎo)致了下拉刷新的時(shí)候,滑動(dòng)事件分發(fā)(此處有伏筆)給recyleview的時(shí)候觸發(fā)了上拉記載,數(shù)據(jù)就會(huì)亂掉。
最后
????OK,既然找到了問(wèn)題所在,解決起來(lái)也就有思路了,原先是滑動(dòng)就觸發(fā),我們只需要判斷一下上滑還是下滑就好了。于是樓主自信滿滿的寫了一個(gè)onTouchEvent來(lái)監(jiān)聽上下滑,結(jié)果現(xiàn)實(shí)總是無(wú)情的,完全沒有作用!嚇得樓主立馬找了大神的demo看了一下,完全沒什么問(wèn)題!最后樓主想到了安卓事件分發(fā)機(jī)制,SwipeRefreshLayout覆蓋掉了onTouchEvent?此處樓主并未深究直接換成dispatchTouchEvent,完美解決!