本文参考:启舰博客
一,简介
Android中的手势检测功能主要在GestureDetector这个类当中,所以主要是对GestureDetector这个类的说明。
GestureDetector类对外提供了两个接口和一个外部类,接口:OnGestureListenerOnDoubleTapListener,内部类:SimpleOnGestureListener

二,OnGestureListener接口
手势检测接口,当有down,move,up事件发生时,会回调其中的方法。
OnGestureListener接口重写必须重写6个方法。

public class GestureListenter 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;    }}
方法 含义
OnDown(MotionEvent e) 发生down事件时会立即调用
onShowPress(MotionEvent e) 用户触发down事件,没触发move或yet事件,且down事件发生时间超过瞬间则调用
onLongPress(MotionEvent e) down事件发生时间超过一定时长,会调用
onSingleTapUp(MotionEvent e) 单独的轻击会调用
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轴上的移动速度,像素/秒
onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) 滑屏调用,且会调用多次
实际操作 调用顺序
轻击 onDown() - onSingleTapup()
短按 onDown() - onShowPress() - onSingleTapUp()
长按 onDown() - onShowPress() - onLongPress()
短按慢划 onDown() - onShowPress() - 多个onScroll() -onFling()
快划 onDown() - 多个onScroll() - onFling()
长按滑动 onDown() - onShowPress() - onLongPress()

总结:当点击时接触屏幕时间超过一定时间会触发onShowPress(),可以作为是否误触的一个判决条件。

public class MainActivity extends AppCompatActivity {    private GestureDetector mGestureDetector;    TextView mTextTv;    @SuppressLint("ClickableViewAccessibility")    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mGestureDetector = new GestureDetector(new GestureListenter());        mTextTv = findViewById(R.id.tv_text);        mTextTv.setFocusable(true);        mTextTv.setClickable(true);        mTextTv.setLongClickable(true);        mTextTv.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                return mGestureDetector.onTouchEvent(event);            }        });    }}public class GestureListenter implements GestureDetector.OnGestureListener {    private static final String TAG = "GestureListenter";    @Override    public boolean onDown(MotionEvent e) {        Log.i(TAG, "onDown: ");        return true;    }    @Override    public void onShowPress(MotionEvent e) {        Log.i(TAG, "onShowPress: ");    }    @Override    public boolean onSingleTapUp(MotionEvent e) {        Log.i(TAG, "onSingleTapUp: ");        return true;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        Log.i(TAG, "onScroll: ");        return true;    }    @Override    public void onLongPress(MotionEvent e) {        Log.i(TAG, "onLongPress: ");    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        Log.i(TAG, "onFling: ");        return true;    }}

需要注意的是onDown()方法应该返回true,否则会导致在慢速滑动况下结束时不会调用onFling()方法,我刚才踩到了。

三,OnDoubleTapListener接口
OnDoubleTapListener是检测屏幕双击的接口。重写时需要重写3个方法

public class DoubleTapListener implements GestureDetector.OnDoubleTapListener {    @Override    public boolean onSingleTapConfirmed(MotionEvent e) {        return false;    }    @Override    public boolean onDoubleTap(MotionEvent e) {        return false;    }    @Override    public boolean onDoubleTapEvent(MotionEvent e) {        return false;    }}
方法 含义
onSingleTapConfirmed(MotionEvent e) 单击确认触发
onDoubleTap(MotionEvent e) 双击时触发
onDoubleTapEvent(MotionEvent e) 双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件。
public class DoubleTapListener implements GestureDetector.OnDoubleTapListener {    private static final String TAG = "WillScorpio";    @Override    public boolean onSingleTapConfirmed(MotionEvent e) {        Log.i(TAG, "onSingleTapConfirmed: ");        return true;    }    @Override    public boolean onDoubleTap(MotionEvent e) {        Log.i(TAG, "onDoubleTap: ");        return true;    }    @Override    public boolean onDoubleTapEvent(MotionEvent e) {        Log.i(TAG, "onDoubleTapEvent: ");        return true;    }}

为了便于观看log,将ListenerTAG设置为一样的。

mGestureDetector.setOnDoubleTapListener(new DoubleTapListener());

再通过上面的代码设置OnDoubleTapListener

事件 调用过程
轻点 onDown() - onSingleTapUp() - onSingleTapConfirmed()
单击 onDown() - onShowPress() - onSingleTapUp() - onSingleTapConfirmed()
轻击两次 onDown() - onSingleTapUp() - onDoubleTap() - onDoubleTapEvent() - onDown() - onDoubleTapEvent()
单击两次 onDown() - onShowPress()- onSingleTapUp() - onDoubleTap() - onDoubleTapEvent() - onDown() - onDoubleTapEvent()
第一次点击第二次点上滑动 onDown() - onShowPress() - onSingleTapUp() - onDoubleTap() - onDoubleTapEvent() - onDown() - 多个onDoubleTapEvent()

总结:1.在第二下点击时,先触发OnDoubleTap,然后再触发OnDown(第二次点击)。
2.在多个onDoubleTapEvent()之间可能会有onShowPress(),onShowPress()不应该作为重要参数。

四,SimpleOnGestureListener内部类
SimpleOnGestureListenerGestureDetector的内部类,它实现了OnGestureListenerOnDoubleTapListener接口,这样做的好处是如果我们只准备重写其中几个方法,不想重写所有接口方法或准备重写所有方法,便可以选择这个内部类,GestureDetector提供了构造方法。

GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);


五,识别左右滑动

识别左右滑动在onFling()这个函数中,e1是刚开始的MotionEvente2是最后的MotionEvent,正常滑动时没问题,但如果做如下图的滑动,会造成混淆。

public class GestureListenter implements GestureDetector.OnGestureListener {    private static final String TAG = "WillScorpio";    final int FLING_MIN_DISTANCE = 100;    final int FLING_MIN_VELOCITY = 200;    @Override    public boolean onDown(MotionEvent e) {        Log.i(TAG, "onDown: ");        return true;    }    @Override    public void onShowPress(MotionEvent e) {        Log.i(TAG, "onShowPress: ");    }    @Override    public boolean onSingleTapUp(MotionEvent e) {        Log.i(TAG, "onSingleTapUp: ");        return true;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        Log.i(TAG, "onScroll: ");        return true;    }    @Override    public void onLongPress(MotionEvent e) {        Log.i(TAG, "onLongPress: ");    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {            Log.i(TAG, "onFling: Left");        }        if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {            Log.i(TAG, "onFling: Right");        }        return true;    }}

更多相关文章

  1. Android中工作线程与主线程同步方式
  2. Android(安卓)多媒体
  3. android中调用系统功能 来显示本地相册图片 拍照 视频 音频功能
  4. Android事件分发和View绘制流程分析(三)
  5. Android(安卓)OnTouchListener OnGestureListener
  6. Android反射机制实例
  7. Android的webView应用与js互调app混合开发用例
  8. Android(安卓)获取当前日期 时间很方便 直接调用Calendar类即可
  9. Android调用相机和相册详解

随机推荐

  1. android 应用内悬浮框,并在指定页面显示
  2. Android Studio 简单介绍和使用问题小结
  3. Android分割线divider(内含Android虚线分
  4. android layout属性介绍
  5. android:layout_gravity与android:gravit
  6. Android初级之路-Android发展史
  7. Android GWES之Android窗口管理
  8. android系统硬件抽象层(HAL)原理及实现之原
  9. Android环境变量配置
  10. Android响应按钮的程序结构