簡介
Android系統中有另一個用來偵測觸控手勢的類別GestureDetector
,和onTouchEvent()
或onTouch
不同的的地方,onTouchEvent()
或onTouch()
是屬於比較廣義的觸控事件,只回應比較基本觸控事件,如:ACTION_DOWN、ACTION_UP、ACTION_MOVE等等。而像雙擊、長按甚至捲動這些較複雜的動作,就無法回應了,如果應用程式內需要支援更進一步的觸控手勢,可以使用GestureDetector
類別來偵測。
GestureDetector
類別內提供兩個介面和一個子類別:
interface | GestureDetector.OnDoubleTapListener | 該介面用來通知雙擊或是單擊確認事件。 |
interface | GestureDetector.OnGestureListener | 該介面用來通知有手勢動作發生的事件。 |
class | GestureDetector.SimpleOnGestureListener | 一個方便的手勢偵測集合類別,可以用來繼承並實作你感興趣的事件。 |
建立手勢偵測步驟
- 建立自己的手勢類別並繼承類別
GestureDetector.SimpleOnGestureListener
。 - 建立
GestureDetector
物件。 - 幫你要偵測手勢的View元件加入
onTouchEvent()
或onTouch()
方法。 - 在
onTouchEvent()
或onTouch()
內呼叫GestureDetector.onTouchEvent()
方法,並傳入系統傳來的MotionEvent
物件。在onTouchEvent()
或onTouch()
方法內必須回傳false,否則部分手勢將無法被偵測到。
GestureDetector.SimpleOnGestureListener
支援的手勢:
boolean onDoubleTap(MotionEvent e) | 快速點擊兩次時發生的事件。 |
boolean onDoubleTapEvent(MotionEvent e) | 當快速點擊兩下時,每一下都會發生一次。 |
boolean onDown(MotionEvent e) | 每次點擊時發生(發生時機相當於ACTION_DOWN )。 |
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) | 當滑動了一段距離後,放開時發生的事件。 |
void onLongPress(MotionEvent e) | 點擊並且停留長時間時會發生。 |
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) | 當滑動時會持續發生。 |
void onShowPress(MotionEvent e) | 當使用者點擊後,停留較長一點時間,沒有滑動也還沒放開時會發生。 |
boolean onSingleTapConfirmed(MotionEvent e) | 單擊並且沒有發生雙擊事件時發生。Notified when a single-tap occurs. |
boolean onSingleTapUp(MotionEvent e) | 單擊放開時或是雙擊事件的第一下方開時會發生。 |
範例
在自定義SimpleOnGestureListener
類別內使用快速鍵Ctrl+O
並加入覆寫(override)所有手勢事件方法。

import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.View.OnLongClickListener; import android.view.View.OnTouchListener; import android.widget.TextView; public class MyGestureDetectorActivity extends Activity { TextView txt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_gesture_detector); Log.d("MyGestureDetectorActivity", "onCreate"); txt = (TextView)findViewById(R.id.txt); txt.setText(""); // 清空文字 // 傾聽TextView上的手勢,該元件layout_width和layout_height皆為match_parent txt.setOnTouchListener(new OnTouchListener() { // 建立GestureDetector物件,並傳入自己定義的手勢物件(繼承自SimpleOnGestureListener) GestureDetector gd = new GestureDetector(MyGestureDetectorActivity.this, new MyGestureDetectorListener()); @Override public boolean onTouch(View v, MotionEvent event) { // 呼叫GestureDetector的onTouchEvent()方法,傳入收到的MotionEvent物件 gd.onTouchEvent(event); return false; } }); } public void addText(String str) { txt.setText(str + "\n" + txt.getText().toString()); } // 自行定義的手勢物件 class MyGestureDetectorListener extends SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent e) { Log.d("MyGestureDetectorListener", "onSingleTapUp"); addText("onSingleTapUp"); return super.onSingleTapUp(e); } @Override public void onLongPress(MotionEvent e) { Log.d("MyGestureDetectorListener", "onLongPress"); addText("onLongPress"); super.onLongPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.d("MyGestureDetectorListener", "onScroll"); addText("onScroll"); return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.d("MyGestureDetectorListener", "onFling"); addText("onFling"); return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onShowPress(MotionEvent e) { Log.d("MyGestureDetectorListener", "onShowPress"); addText("onShowPress"); super.onShowPress(e); } @Override public boolean onDown(MotionEvent e) { Log.d("MyGestureDetectorListener", "onDown"); addText("onDown"); return super.onDown(e); } @Override public boolean onDoubleTap(MotionEvent e) { Log.d("MyGestureDetectorListener", "onDoubleTap"); addText("onDoubleTap"); return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.d("MyGestureDetectorListener", "onDoubleTapEvent"); addText("onDoubleTapEvent"); return super.onDoubleTapEvent(e); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.d("MyGestureDetectorListener", "onSingleTapConfirmed"); addText("onSingleTapConfirmed"); return super.onSingleTapConfirmed(e); } } }