原生的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滑動的流暢性
