Google了一下,終於搞清了touch screen下的幾種操作模式(對應的是事件)。
對於一個view, 常用的操作有點擊(click)和長按(long press)二種。實際上,這些操作類型是Android內部在onTouchEvent(MotionEvent event)里對用戶的動作做了一定的分析,從而通知應用程序是發生了點擊還是長按等事件。
有時,我們需要的並不僅限於這兩種操作。我們可以借助GestureDetector來分析出更細致的操作類型。基本的過程就是創建一個myGestureDetector對象,傳入自己定義的myOnGestureListener對象,在自己的onTouchEvent回調函數中將接收到的event傳給myGestureDetector進行分析,myOnGestureListener會回調我們定義的動作。
【 從 GestureDetector.SimpleOnGestureListener派生出myListener 會更簡單,因為這個類已經實現了全部接口,只是沒有什么實際有用的功能。】
參考以下代碼(for an Activity):
// -------------------------------------------------------------------------------
private GestureDetector mGestureDetector;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGestureDetector = new GestureDetector(this, new MyGestureListener());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
class MyGestureListener extends GestureDetector.OnGestureListener{ //共有6個方法:
// 用戶輕觸觸屏:Touch down(僅一次)時觸發, e為down時的MotionEvent:
boolean onDown(MotionEvent e){return true;}
// 用戶輕觸觸屏,且尚未松開或拖動:
// 在Touch down(僅一次)之后一定時間(115ms)觸發,e為down時的MotionEvent:
void onShowPress(MotionEvent e){return true;}
// 用戶(輕觸觸屏后)松開:Touch up(僅一次)時觸發,e為up時的MotionEvent:
boolean onSingleTapUp(MotionEvent e){return true;}
// 用戶輕觸觸屏,並拖動:
// 按下並滑動時觸發,e1為down(僅一次)時的MotionEvent,e2為move(多個)時的MotionEvent:
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){return true;}
// 用戶長按觸屏(此View必須是可長按的: myView->setLongClickable(true);):
// 在Touch down之后一定時間(500ms)后,由多個down事件觸發,e為down時的MotionEvent:
void onLongPress(MotionEvent e){return true;}
// 用戶按下觸屏、快速移動后松開:
// 按下並快速滑動一小段距離(多個move),up時觸發,e1為down(僅一次)時的MotionEvent,
// e2為up(僅一次)時的MotionEvent:
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){return true;}
}
// -------------------------------------------------------------------------------
至於doubletap的檢測,可以通過設置mGestureDetector的OnDoubleTapListener來實現:
GestureDetector.OnDoubleTapListener doubleTapListener = new GestureDetector.OnDoubleTapListener() {
// 完成一次單擊,並確定(300ms內)沒有發生第二次單擊事件后觸發,e為down時的MotionEvent:
boolean onSingleTapConfirmed(MotionEvent e){return true;}
// 第二次單擊down時觸發,e為第一次down時的MotionEvent:
boolean onDoubleTap(MotionEvent e){return true;}
// 第二次單擊down、move和up時都觸發,e為不同時機下的MotionEvent:
boolean onDoubleTapEvent(MotionEvent e){return true;}
}
mGestureDetector.setDoubleTapListener(doubleTapListener);
// -------------------------------------------------------------------------------
具體地說,典型的觸屏事件及其listener執行的流程見下:
1). 單擊事件的執行流程:
有兩種情況,一種是時間很短,一種時間稍長。
時間很短:onDown ----> onSingleTapUp ----> onSingleTapConfirmed
時間稍長:onDown ----> onShowPress ----> onSingleTapUp ----> onSingleTapConfirmed
2). 長按事件
onDown ----> onShowPress ----> onLongPress
3.拋(fling):手指觸動屏幕后,稍微滑動后立即松開:
onDown ----> onScroll ----> onScroll ----> onScroll ----> ……… ----> onFling
4.拖動(drag)
onDown ----> onScroll ----> onScroll ----> onFiling
注意:有的時候會觸發onFiling,但是有的時候不會觸發,z這是因為人的動作不標准所致。
<完>