1. 程式人生 > >Android 2.3中ListView偶爾未正常通知已註冊的OnScrollListener

Android 2.3中ListView偶爾未正常通知已註冊的OnScrollListener

分析原始碼,初步斷定原因:

當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));

效果待測!
原文位置:

http://yanlijun250.iteye.com/blog/1438303

http://code.google.com/p/android/issues/detail?id=5086