深圳幻海软件技术有限公司 欢迎您!

Android 手势检测 - GestureDetector 全面分析

2023-03-01

本文转载自微信公众号「Android开发编程」,作者Android开发编程。转载本文请联系Android开发编程公众号。前言当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等;Androidsdk给我们提供了GestureDetector类,通过这个类我们可以识

本文转载自微信公众号「Android开发编程」,作者Android开发编程。转载本文请联系Android开发编程公众号。

前言

当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等;Android sdk给我们提供了GestureDetector类,通过这个类我们可以识别很多的手势;今天就来学习下。

一、GestureDetector介绍

GestureDetector这个类对外提供了两个接口和一个外部类

  • 接口:OnGestureListener,OnDoubleTapListener
  • 内部类: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


  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

这里总共重写了六个函数

1、OnDown(MotionEvent e):用户按下屏幕就会触发;

2、onShowPress(MotionEvent e):如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动的,那么onShowPress就会执行

3、onLongPress(MotionEvent e):长按触摸屏,超过一定时长,就会触发这个事件,触发顺序:onDown->onShowPress->onLongPress

4、onSingleTapUp(MotionEvent e):一次单独的轻击抬起操作,也就是轻击一下屏幕,立刻抬起来,才会有这个触发,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,所以也就不会触发这个事件;触发顺序:Touchup:onDown->onSingleTapUp->onSingleTapConfirmed ;

onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发;

参数解释:

  • e1:第1个ACTION_DOWN MotionEvent
  • e2:最后一个ACTION_MOVE MotionEvent
  • velocityX:X轴上的移动速度,像素/秒
  • velocityY:Y轴上的移动速度,像素/秒

5、onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖动事件;无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法在ACTION_MOVE动作发生时就会触发;

滑屏:手指触动屏幕后,稍微滑动后立即松开

onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling

拖动

onDown------》onScroll----》onScroll------》onFiling

无论是滑屏,还是拖动,影响的只是中间OnScroll触发的数量多少而已,最终都会触发onFling事件;

二、实现GestureDetector

1、实现OnGestureListener接口中的方法(可以使用匿名内部类或实现了接口的类实例);

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
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

2、创建GestureDetector类的实例,构造函数如下:

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()); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

3、 实现View.OnTouchListener接口,重写onTouch()方法

4、在onTouch()方法中拦截事件处理,将控制权交给GestureDector;

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    return mGestureDetector.onTouchEvent(event); 

  • 1.
  • 2.
  • 3.
  • 4.

5、调用控件的View.setOnTouchListener()将接口的具体实现的引用传递进去或者如果是监听双击的话调用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()); 
    } 
    /* 
     * 当该view上的事件被分发到view上时触发该方法的回调 
     * 如果这个方法返回false时,该事件就会被传递给Activity中的onTouchEvent方法来处理 
     * 如果该方法返回true时,表示该事件已经被onTouch函数处理玩,不会上传到activity中处理 
     * 该方法属于View.OnTouchListening接口 
     */ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
        return mGestureDetector.onTouchEvent(event); 
    } 
    /* 
     * 手势监听类 
     */ 
    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
        } 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.

自定义控件继承了View实现了View.OnTouchListener。监听的方法用的是继承SimpleOnGestureListener类,重写了所有方法;

总结 

本文只是给了基本的用法,后面会介绍下源码。