Android 手勢檢測 - GestureDetector 全面分析
本文轉(zhuǎn)載自微信公眾號「Android開發(fā)編程」,作者Android開發(fā)編程。轉(zhuǎn)載本文請聯(lián)系A(chǔ)ndroid開發(fā)編程公眾號。
前言
當(dāng)用戶觸摸屏幕的時候,會產(chǎn)生許多手勢,例如down,up,scroll,filing等等;Android sdk給我們提供了GestureDetector類,通過這個類我們可以識別很多的手勢;今天就來學(xué)習(xí)下。
一、GestureDetector介紹
GestureDetector這個類對外提供了兩個接口和一個外部類
- 接口:OnGestureListener,OnDoubleTapListener
- 內(nèi)部類:SimpleOnGestureListener
GestureDetector類介紹
- private class Gesturelistener implements GestureDetector.OnGestureListener{
- public boolean onDown(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- public void onShowPress(MotionEvent e) {
- // TODO Auto-generated method stub
- }
- public boolean onSingleTapUp(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- public boolean onScroll(MotionEvent e1, MotionEvent e2,
- float distanceX, float distanceY) {
- // TODO Auto-generated method stub
- return false;
- }
- public void onLongPress(MotionEvent e) {
- // TODO Auto-generated method stub
- }
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // TODO Auto-generated method stub
- return false;
- }
- }
這里總共重寫了六個函數(shù)
1、OnDown(MotionEvent e):用戶按下屏幕就會觸發(fā);
2、onShowPress(MotionEvent e):如果是按下的時間超過瞬間,而且在按下的時候沒有松開或者是拖動的,那么onShowPress就會執(zhí)行
3、onLongPress(MotionEvent e):長按觸摸屏,超過一定時長,就會觸發(fā)這個事件,觸發(fā)順序:onDown->onShowPress->onLongPress
4、onSingleTapUp(MotionEvent e):一次單獨的輕擊抬起操作,也就是輕擊一下屏幕,立刻抬起來,才會有這個觸發(fā),當(dāng)然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以也就不會觸發(fā)這個事件;觸發(fā)順序:Touchup:onDown->onSingleTapUp->onSingleTapConfirmed ;
onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :滑屏,用戶按下觸摸屏、快速移動后松開,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE, 1個ACTION_UP觸發(fā);
參數(shù)解釋:
- e1:第1個ACTION_DOWN MotionEvent
- e2:最后一個ACTION_MOVE MotionEvent
- velocityX:X軸上的移動速度,像素/秒
- velocityY:Y軸上的移動速度,像素/秒
5、onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖動事件;無論是用手拖動view,或者是以拋的動作滾動,都會多次觸發(fā),這個方法在ACTION_MOVE動作發(fā)生時就會觸發(fā);
滑屏:手指觸動屏幕后,稍微滑動后立即松開
onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
拖動
onDown------》onScroll----》onScroll------》onFiling
無論是滑屏,還是拖動,影響的只是中間OnScroll觸發(fā)的數(shù)量多少而已,最終都會觸發(fā)onFling事件;
二、實現(xiàn)GestureDetector
1、實現(xiàn)OnGestureListener接口中的方法(可以使用匿名內(nèi)部類或?qū)崿F(xiàn)了接口的類實例);
- class MyGestureListener implements GestureDetector.OnGestureListener {
- @Override
- public boolean onDown(MotionEvent e) {
- return false;
- }
- @Override
- public void onShowPress(MotionEvent e) {
- }
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- return false;
- }
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- return false;
- }
- @Override
- public void onLongPress(MotionEvent e) {
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- return false;
- }
- }
2、創(chuàng)建GestureDetector類的實例,構(gòu)造函數(shù)如下:
- public GestureDetector(OnGestureListener listener, Handler handler) {
- this(null, listener, handler);
- }
- public GestureDetector(OnGestureListener listener) {
- this(null, listener, null);
- }
- public GestureDetector(Context context, OnGestureListener listener) {
- this(context, listener, null);
- }
- public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
- }
- public GestureDetector(Context context, OnGestureListener listener, Handler handler,
- boolean unused) {
- this(context, listener, handler);
- }
- mGestureDetector = new GestureDetector(mContext,new MyGestureListener());
3、 實現(xiàn)View.OnTouchListener接口,重寫onTouch()方法
4、在onTouch()方法中攔截事件處理,將控制權(quán)交給GestureDector;
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return mGestureDetector.onTouchEvent(event);
- }
5、調(diào)用控件的View.setOnTouchListener()將接口的具體實現(xiàn)的引用傳遞進去或者如果是監(jiān)聽雙擊的話調(diào)用GestureDetector .setOnDoubleTapListener()
- package com.test.test;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.GestureDetector;
- import android.view.MotionEvent;
- import android.view.View;
- /*
- *
- */
- public class MyView extends View implements View.OnTouchListener{
- private Context mContext;
- private GestureDetector mGestureDetector;
- private static final String TAG = "MyView";
- public MyView(Context context) {
- super(context);
- initData(context);
- }
- public MyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initData(context);
- }
- public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initData(context);
- }
- private void initData(Context context) {
- this.mContext = context;
- super.setOnTouchListener(this);
- super.setClickable(true);
- super.setLongClickable(true);
- super.setFocusable(true);
- mGestureDetector = new GestureDetector(mContext,new MyGestureListener());
- mGestureDetector.setOnDoubleTapListener(new MyGestureListener());
- }
- /*
- * 當(dāng)該view上的事件被分發(fā)到view上時觸發(fā)該方法的回調(diào)
- * 如果這個方法返回false時,該事件就會被傳遞給Activity中的onTouchEvent方法來處理
- * 如果該方法返回true時,表示該事件已經(jīng)被onTouch函數(shù)處理玩,不會上傳到activity中處理
- * 該方法屬于View.OnTouchListening接口
- */
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return mGestureDetector.onTouchEvent(event);
- }
- /*
- * 手勢監(jiān)聽類
- */
- class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
- public MyGestureListener() {
- super();
- }
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- Log.e(TAG, "onDoubleTap");
- return true;
- }
- @Override
- public boolean onDoubleTapEvent(MotionEvent e) {
- Log.e(TAG, "onDoubleTapEvent");
- return true;
- }
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- Log.e(TAG, "onSingleTapConfirmed");
- return true;
- }
- @Override
- public boolean onContextClick(MotionEvent e) {
- Log.e(TAG, "onContextClick");
- return true;
- }
- @Override
- public boolean onDown(MotionEvent e) {
- Log.e(TAG, "onDown");
- return true;
- }
- @Override
- public void onShowPress(MotionEvent e) {
- Log.e(TAG, "onShowPress");
- }
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- Log.e(TAG, "onSingleTapUp");
- return true;
- }
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- Log.e(TAG, "onScroll");
- return true;
- }
- @Override
- public void onLongPress(MotionEvent e) {
- Log.e(TAG, "onLongPress");
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- Log.e(TAG, "onFling");
- return true;
- }
- }
- }
自定義控件繼承了View實現(xiàn)了View.OnTouchListener。監(jiān)聽的方法用的是繼承SimpleOnGestureListener類,重寫了所有方法;
總結(jié)
本文只是給了基本的用法,后面會介紹下源碼。