本文参考:启舰博客
一,简介
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);

Android手势检测简介_第1张图片
五,识别左右滑动

识别左右滑动在onFling()这个函数中,e1是刚开始的MotionEvente2是最后的MotionEvent,正常滑动时没问题,但如果做如下图的滑动,会造成混淆。
Android手势检测简介_第2张图片

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中Bitmap的放大和缩小的方法
  2. Android遍历文件Listfile返回值为null问题解决方法适用Android8.
  3. Android 最新获取手机内置存储大小,SD卡存储空间大小方法
  4. Android 启动浏览器的方法
  5. Android根据电量变化为不同图片的方法【电池电量提示】
  6. Android之日期时间选择器使用方法
  7. Android 图片旋转(使用Matrix.setRotate方法)
  8. Android Http请求失败解决方法
  9. Glide的with()方法和生命周期的源码分析

随机推荐

  1. 关于Android的post,get、cookie网络获取的
  2. windows10 环境下编译 Android(安卓)Pjsi
  3. Android模拟器访问Tomcat和IIS7
  4. [Android]获取其他应用的logcat
  5. Android 手势的识别和控制 GestureDeteco
  6. 4.0后configChanges失效的解决
  7. Android(安卓)上成功实现了蓝牙的一些Pro
  8. android proc 进程信息解析
  9. iOS 与 Android 生命周期对比
  10. 单项选择RadioButton和多项选择CheckBox