GestureDetector
爲什麼要使用 GestureDetector 類?因爲使用它可以很輕鬆的監聽單擊,雙擊,按下等許多手勢事件的發生,並且做出相應的處理。GestureDetector 類使用了 MotionEvent 提供的方法來監聽事件發生,並且調用 GestureDetector 提供的回調方法來給與一個反饋。想要使用 GestureDetector 類需要完成以下工作
GestureDetector 的構造函數
爲指定視圖創建一個 GestureDetector 的實例
在 Activity 中調用 onTouchEvent(MotionEvent) 方法,借用此方法,調用 GestureDetector 提供給我們的 onTouchEvent(MotionEvent) 方法。
下面來執行第一步,也即創建一個 GestureDetector 實例,而創建該實例有三個方法,就是說它有三個構造函數
1.GestureDetector(Context context,GestureDetector.onGestureListener listener)
2.GestureDetector((Context context, GestureDetector.OnGestureListener listener, Handler handler) //該方法提供了一個Handler 對象,因此該構造方法實例化的對象可以處理一些獨立於主線程且延遲的操作
3.GestureDetector (Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused)
介紹完了構造函數,下面就來詳細介紹一下 GestureDetector 相關的一些接口和具體類
GestureDetector 相關的接口和具體類
1.interface GestureDetector.OnContextClickListener
這是一個簡單的接口,其中只包含一個方法,也即 onContextClick(MotionEvent e) ,用於監聽一個Context被點擊的事件,值得注意的是,使用這個接口時,我們應該調用 onGenericMotionEvent(MotionEvent) 方法去監聽時間的發生。
2.interface GestureDetector.OnDoubleTapListener, 聽名字就知道,這個接口主要用於監聽雙擊事件。這個接口中有三個方法。
public abstract boolean onDoubleTap (MotionEvent e) //監聽雙擊事件
public abstract boolean onDoubleTapEvent (MotionEvent e) //這個方法比上述方法強一些,不僅可以監聽雙擊事件,連續移動兩次或者擡起兩次,都可以觸發該方法。
public abstract boolean onSingleTapConfirmed (MotionEvent e) //這個方法可以監聽單擊事件,這裏的單擊事件是指確定只點擊了一次沒有在點擊第二次,和GestureDetector.OnGestureListener 中的 onSingleTapUp(MotionEvent e) 方法是不同的。
3.interface GestureDetector.OnGestureListener 這個接口就是實例化 GestureDetector 所必須提供的 Listener, 這個方法中提供了六個方法。
public abstract boolean onDown (MotionEvent e) //監聽按下事件
public abstract boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) // 監聽快速滑動事件,參數 e1 是剛按下時的那個 Motionevent,e2是滑動時的那個 MotionEvent,velocityX 是在 x 軸上的滑動速率,velocityY 是在 y 軸上的滑動速率。
public abstract void onLongPress (MotionEvent e) //監聽長點擊事件
public abstract boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) // 監聽滾動事件,參數和onFling 類似
public abstract void onShowPress (MotionEvent e) // 如果用戶一直按着界面不擡起,就會觸發該方法,該方法和 onLongPress() 方法不同,因爲 onLongPress() 只有在用戶長點擊之後擡起纔會觸發,而該方法不擡起照樣會觸發。
public abstract boolean onSingleTapUp (MotionEvent e) // 單擊並擡起會觸發該方法
4.GestureDetector.SimpleOnGestureListener
這是一個具體類,繼承自GestureDetector.OnGestureListener GestureDetector.OnDoubleTapListener GestureDetector.OnContextClickListener 這三個接口,並且提供了默認實現,這也就是說我們可以寫一個子類繼承它,並且複寫我們想要的方法,有點類似 Java GUI 中的 Adapter 類 。
使用 GestureDetector.OnGestureListener
public class MyOnGestureListener implements GestureDetector.OnGestureListener{
private Context mContext;
public MyOnGestureListener(Context context){
mContext = context;
}
@Override
public boolean onDown(MotionEvent motionEvent) {
Toast.makeText(mContext, "onDown ", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
Toast.makeText(mContext, "onShowPress",Toast.LENGTH_SHORT).show();
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
Toast.makeText(mContext, "onSingleTapUp", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Toast.makeText(mContext, "onScroll", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
Toast.makeText(mContext, "onLongPress", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Toast.makeText(mContext, "onFling", Toast.LENGTH_SHORT).show();
return true;
}
}
public class MainActivity extends AppCompatActivity {
private GestureDetector mDetector;
private MyOnGestureListener mGestureListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGestureListener = new MyOnGestureListener(this);
mDetector = new GestureDetector(this, mGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
}
請注意,在以上各個函數的實現中,凡是返回值爲 boolean 的,都要返回 true 這樣方法才能在具體事件發生時被調用,否則該方法不會被事件觸發。 在以上方法的實現中,只是簡單的調用了 toast 方法,其實在這裏我們可以完成很多功能。
可見使用該方法有一個缺陷,就是我們需要爲所有方法提供一個實現,包括我們不想要的方法,這是非常耽誤時間的,所以纔有了 GestureDetector.SimpleOnGestureListener
使用 GestureDetector.SimpleOnGestureListener
public class MySimpleGesture extends GestureDetector.SimpleOnGestureListener{
private Context mContext;
public MySimpleGesture(Context context){
mContext = context;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(mContext, "Double Tap", Toast.LENGTH_SHORT).show();
return true;
}
}
public class MainActivity extends AppCompatActivity {
private GestureDetector mDetector;
private MySimpleGesture mSimpleGesture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSimpleGesture = new MySimpleGesture(this);
mDetector = new GestureDetector(this, mSimpleGesture);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
}
可以在 MySimpleGesture 類中實現自己需要的方法。