原生的ScrollView並沒有實現類似ListView的onScrollListener的接口,在開發中需要監聽ScrollView滑動狀態,比如滑動到頂部(底部),滑動的距離等等。
在onTouchListener中可以監聽到用戶的點擊行為,但是ScrollView在MotionEvent.Action_UP之后還會滑動一段距離,這時候就需要起一個延時的handler,這個handler實時記錄當前ScrollView的滑動距離,以此來判斷滑動狀態
interface onScrollListener{
void onScrollStop();
void onScroll(int y);
}
scrollView.setOnTouchListener(new OnTouchListener() { private int lastY = 0; private int touchEventId = 1001;
private OnScrollListener listener; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); View scroller = (View) msg.obj; if (msg.what == touchEventId) { if (lastY == scroller.getScrollY()) { //滑動停止
listener.onScrollStop(); } else { handler.sendMessageDelayed(handler.obtainMessage(touchEventId, scroller), 1); lastY = scroller.getScrollY();
listener.onScroll(lastY); } } } }; @Override public boolean onTouch(View v, MotionEvent event) { isScoll = false; int eventAction = event.getAction(); int y = (int) event.getRawY(); switch (eventAction) { case MotionEvent.ACTION_UP: handler.sendMessageDelayed(handler.obtainMessage(touchEventId, v), 5); break; default: break; } return false; } });
此方法可行,但是實現起來頗為麻煩,監聽的靈敏度和效率都比較低。在ScrollView中嘗試去重寫其中的onScrollChanged方法,並將其參數通過接口暴露出來,可以實現對ScrollView滑動事件的監聽。
onScrollChanged有四個參數,官方文檔對其介紹如下
This is called in response to an internal scroll in this view (i.e., the view scrolled its own contents). This is typically as a result of scrollBy(int, int)
or scrollTo(int, int)
having been called.
- Parameters:
- l Current horizontal scroll origin.
- t Current vertical scroll origin.
- oldl Previous horizontal scroll origin.
- oldt Previous vertical scroll origin.
t是當前上下滑動的位置,oldt上一次滑動的位置,通過處理t和oldt,可以判斷當前的滑動狀態,如滑動到頂部,滑動到底部,滑動方向等,從而實現對ScrollView滑動的監聽。當然我並不建議在這個方法中進行非常耗時的處理和計算,可能影響ScrollView滑動的流暢性