GestureDetector:GestureDetectorCompat
用於在點擊和長按以外,增長其餘手勢的監聽,好比雙擊、滑動。經過View.onTouchEvent()
裏調用GestyreDetector.onTouchEvent(),以代理的形式來實現:bash
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
複製代碼
有一個默任監聽器:GestureDetector.OnGestureListener
OnGestureListener
的幾個回調方法:ide
@Override
public boolean onDown(MotionEvent e) {
// 每次 ACTION_DOWN 事件出現的時候都會被調用,在這里返回 true能夠保證必然消費掉事件
return true;
}
@Override
public void onShowPress(MotionEvent e) {
// 用戶按下 100ms不鬆手後會被調用,用於標記「能夠顯示按下狀態了了」
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// 用戶單擊時被調用(長按後鬆手不會調用、雙擊的第二下時不會被調用)
return false;
}
@Override
public boolean onScroll(MotionEvent downEvent, MotionEvent event, floatdistanceX, float distanceY) {
// 用戶滑動時被調用
// 第一個事件是⽤用戶按下時的 ACTION_DOWN 事件,第二個事件是當前事件
// 偏移是按下時的位置 - 當前事件的位置
return false;
}
@Override
public void onLongPress(MotionEvent e) {
//⽤用戶長按(按下 500ms 不鬆手)後會被調用
// 這個 500ms 在 GestureDetectorCompat 中變成了了 600ms (???)
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {
//⽤用於滑動時迅速擡起時被調用,用於用戶但願控件進行慣性滑動的場景
return false;
}
複製代碼
OnDoubleTapListener
:雙擊監聽器 gestureDetector.setOnDoubleTapListener(doubleTapListener);
回調方法有下面這些:post
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// ⽤用戶單擊時被調⽤用
// 和 onSingltTapUp() 的區別在於,⽤用戶的一次點擊不會當即調用這個⽅方法,而是在必定
時間後(300ms),確認用戶沒有進行雙擊,這個方法纔會被調用
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// 用戶雙擊時被調用
// 注意:第二次觸摸到屏幕時就調用,⽽而不不是擡起時
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
// ⽤用戶雙擊第二次按下時、第二次按下後移動時、第二次按下後擡起時都會被調用
// 經常使用於「雙擊拖拽」的場景
return false;
}
複製代碼
OverScroller:用於自動計算滑動的偏移,經常使用語onFling()
方法中,調用OverScroller.fling()
方法來啓動慣性滑動的計算:動畫
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {
// 初始化滑動
scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
// 下一幀刷新
postOnAnimation(flingRunner);
return false;
}
...
@Override
public void run() {
// 計算此時的位置,而且若是滑動已經結束,就中止
if (scroller.computeScrollOffset()) {
// 把此時的位置應⽤用於界⾯面
offsetX = scroller.getCurrX();
offsetY = scroller.getCurrY();
invalidate();
// 下一幀刷新
postOnAnimation(this);
}
}
複製代碼
VelocityTracker:若是GestureDetector不能知足需求,或者GestureDetector過於複雜,能夠本身處理onTouchEvent的事件。使用VelocityTracker計算手指的移動速度。 使用方法:ui
scrollTo/scrollBy和computeScroll():this
scrollTo()/scrollBy()會設置繪製時的偏移,一般用於滑動控件設置偏移spa
scroll值表示繪製行爲在控件內部的起始偏移(相似:我要從內容的第300個像素開始繪製),所以scrollTo()內的參數填正值是,繪製內容會向負向移動代理
scrollTo()是瞬時方法,不會自動使用動畫。若是要用動畫,須要配合View.computeScroll()方法code
① computeScroll()在View重繪時被自動調用事件
② 使用方式:
// onTouchEvent() 中:
overScroller.startScroll(startX, startY, dx, dy);
postInvalidateOnAnimation();
......
// onTouchEvent() 外:
@Override
public void computeScroll() {
if (overScroller.computeScrollOffset()) { // 計算實時位置
scrollTo(overScroller.getCurrX(), overScroller.getCurrY()); // 更新界面
postInvalidateOnAnimation(); // 下一幀繼續
}
}
複製代碼