手勢,其實是指使用者手指或觸摸筆在觸摸屏上的連續觸碰行為,比如,在螢幕上從左到右劃出的一個動作,就是手勢。再比如在螢幕上畫出一個圓圈也是手勢。
手勢這種連續的觸碰會形成某個方向上的移動趨勢,也會形成一個不規則的幾何圖形,android提供了手勢檢測,并為兩種手勢行為都提供了支援:對于第一種,android提供了手勢檢測,并為手勢檢測提供了相應的監聽器。
對于第二種,Android允許開發者添加手勢,并提供了相應的API識别使用者手勢
GestureDetector.OnGestureListener
1.GestureDetector類:
Android為手勢檢測提供了一個GestureDetector類,GestureDetector執行個體代表了一個手勢檢測器,建立GestureDetector時需要傳入一個GestureDetector.OnGestureListener 執行個體。
GestureDetector.OnGestureListener就是一個監聽器,負責對使用者手勢提供相應。
GestureDetector.OnGestureListener中包含的事件處理方法:
-
boolean onDoubleTap(MotionEvent e)
解釋:輕按兩下的第二下Touch down時觸發
-
boolean onDoubleTapEvent(MotionEvent e)
解釋:輕按兩下的第二下Touch down和up都會觸發,可用e.getAction()區分。
-
boolean onDown(MotionEvent e)
解釋:Touch down時觸發
-
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解釋:Touch了滑動一點距離後,up時觸發。velocityX,是在x軸上滑動的速度。
-
void onLongPress(MotionEvent e)
解釋:Touch了不移動一直Touch down時觸發
-
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解釋:Touch了滑動時觸發。
-
void onShowPress(MotionEvent e)
解釋:Touch了還沒有滑動時觸發
(與onDown,onLongPress比較
onDown隻要Touch down一定立刻觸發。
而Touchdown後過一會沒有滑動先觸發onShowPress再是onLongPress。
是以Touchdown後一直不滑動,onDown->onShowPress->onLongPress這個順序觸發。
- boolean onSingleTapConfirmed(MotionEvent e)
-
boolean onSingleTapUp(MotionEvent e)
解釋:上面這兩個函數都是在touch down後又沒有滑動(onScroll),又沒有長按(onLongPress),然後Touchup時觸發。
-
點選一下非常快的(不滑動)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
-
點選一下稍微慢點的(不滑動)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
注:
1)由于如果實作監聽器,需要重寫所有的方法,我們可以發現可以實作GestureDetector下的一個子類SimpleOnGestureListener,然後重寫其中的某個方法即可。
2)注意onFling和onSroll的差別。
2.使用步驟:
1)建立GestureDetector對象,必須實作監聽器或者建立其下的SimpleOnGestureListener子類的一個匿名内部類。
2)為Activity(偶爾也可以是特定的元件)的TouchEvent時間綁定監聽器,在事件進行中指定把Activity(或元件)的TouchEvent事件交給GestureDetector處理:
例:
@Override
public boolean onTouchEvent(MotionEvent event) {
mGesture.onTouchEvent(event);//将手勢和按鈕綁定
return super.onTouchEvent(event);
}
注意的要點:每個方法中如果要執行,必須return true;
範例:
功能:為按鈕添加輕按兩下手勢,并添加輕按兩下的事件。
思路:
手勢:
1)定義一個手勢變量。
2)new一個手勢執行個體,并在其中添加監聽,監聽輕按兩下事件(),重寫其輕按兩下的方法onDoubleTap();
3)在onTouch方法中:手勢與Button綁定。
添加按鈕的輕按兩下監聽事件:
這是之前将的觀察者模式。不再詳細介紹喽。
手勢中添加滑動,拖動的效果:
onFling()方法實作滑動,僅滑動完才進行動畫效果。
onScroll()方法實作跟随拖動,view随手指移動。
下面呈上代碼:
主活動:
public class MainActivity extends Activity {
private MyButton button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (MyButton) findViewById(R.id.buttonGesture);
button.setOnDoubleListener(new MyButton.onDoubleListener() {
@Override
public void onDoubleClickListener(View view) {
Log.d("mytouch","get touch");
}
});
}
}
自定義Button:
public class MyButton extends Button {
private GestureDetector mGesture;
interface onDoubleListener{
public void onDoubleClickListener(View view);
}
private onDoubleListener onDoubleListener;
public MyButton.onDoubleListener getOnDoubleListener() {
return onDoubleListener;
}
public void setOnDoubleListener(MyButton.onDoubleListener onDoubleListener) {
this.onDoubleListener = onDoubleListener;
}
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
//1.new 一個手勢,其中建立一個監聽事件(不使用原來的傳回值)
mGesture = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDoubleTap(MotionEvent e) {
if(onDoubleListener!=null){
onDoubleListener.onDoubleClickListener(MyButton.this);
}
Log.d("mytouch","double touch");
return true;
}
//手勢中來重寫方法
//隻有手松開時才開始動畫效果
// @Override
// public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {//滑動,産生動畫效果
// if(Math.abs(e2.getX()-e1.getX())>50){
// Log.d("myfling", "在x軸滑動");
// ObjectAnimator.ofFloat(MyButton.this,"translationX",getTranslationX(),getTranslationX()+e2.getX()-e1.getX()).setDuration(500).start();
// return true;//一定要傳回true才執行
// }
// return super.onFling(e1, e2, velocityX, velocityY);
// }
@Override//因為隻要手接觸螢幕,一直都調用此方法,是以直接set即可産生拖動的效果
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
setTranslationX(getTranslationX()+e2.getX()-e1.getX());
setTranslationY(getTranslationY()+e2.getY()-e1.getY());
return true;//傳回true才運作此方法
}
});
});
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGesture.onTouchEvent(event);//2.将手勢和按鈕綁定
return super.onTouchEvent(event);
}
}
效果:
輕按兩下效果:
輕按兩下,列印輕按兩下事件的Log和自定義button中手勢監聽的Log。

拖動效果(這裡不再示範滑動效果^^):