天天看點

Android 手勢(Gesture)——手勢檢測

手勢,其實是指使用者手指或觸摸筆在觸摸屏上的連續觸碰行為,比如,在螢幕上從左到右劃出的一個動作,就是手勢。再比如在螢幕上畫出一個圓圈也是手勢。

手勢這種連續的觸碰會形成某個方向上的移動趨勢,也會形成一個不規則的幾何圖形,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。

Android 手勢(Gesture)——手勢檢測
Android 手勢(Gesture)——手勢檢測

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

Android 手勢(Gesture)——手勢檢測