Android 2.3中ListView偶爾未正常通知已註冊的OnScrollListener
阿新 • • 發佈:2019-01-08
分析原始碼,初步斷定原因:
當ListView滾動到最底部(最頂部)時,觸發了2.3新引入的視覺特效。這部分邏輯裡看到了特效相關的程式碼,但卻沒找到通知reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE)的相關程式碼。其它地方通知reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE)的地方伴隨著mTouchMode = TOUCH_MODE_REST,而特效程式碼這裡卻只有mTouchMode = TOUCH_MODE_REST,無reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE),原始碼如下:
void startSpringback() { Log.d(tag, "simba startSpringback"); if (mScroller.springBack(0, mScrollY, 0, 0, 0, 0)) { mTouchMode = TOUCH_MODE_OVERFLING; invalidate(); post(this); } else { mTouchMode = TOUCH_MODE_REST; //這裡沒有呼叫下面註釋的程式碼,導致ListView註冊的OnScrollListener不會得到通知 //reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } }
在網上找到相關的解決方法如下:
為ListView設定一個OnTouchListener,在這個OnTouchListener中當MotionEvent的action等於 MotionEvent.ACTION_UP或者MotionEvent.ACTION_CANCEL時強制呼叫一次
onScrollStateChanged((AbsListView) view,OnScrollListener.SCROLL_STATE_FLING),
然後再呼叫一次
onScrollStateChanged((AbsListView) view,OnScrollListener.SCROLL_STATE_IDLE)
程式碼如下:
public class FingerTracker implements View.OnTouchListener {
private OnScrollListener myOnScrollListener;
public FingerTracker(OnScrollListener onScrollListener) {
myOnScrollListener = onScrollListener;
}
@Override
public boolean onTouch(View view, MotionEvent event) {
final int action = event.getAction();
boolean mFingerUp = action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_CANCEL;
if (mFingerUp) {
myOnScrollListener.onScrollStateChanged((AbsListView) view,
OnScrollListener.SCROLL_STATE_FLING);
myOnScrollListener.onScrollStateChanged((AbsListView) view,
OnScrollListener.SCROLL_STATE_IDLE);
}
return false;
}
}
為ListView設定自定義的OnTouchListener:
mListView.setOnTouchListener(new FingerTracker(this));
效果待測!
原文位置: