引言
在 android 开发过程中,我们经常需要对一些手势,如:单击、双击、长按、滑动、缩放等,进行监测。这时也就引出了手势监测的概念,所谓的手势监测,说白了就是对于 GestureDetector 的用法的使用和注意要点的学习。注:由于缩放手势独有的复杂性,我打算后期将其单独拿出来归纳总结。
像网上其他将手势监听的博客一样,本文将以双击事件为引子,逐步展开探讨 Android 手势监听,你需要知道的点点滴滴,还是那句话:看完这篇还不会 GestureDetector 手势检测,我跪搓衣板!
双击 666
对于一个 Android 新手而言,如果需要你实现一个双击功能,我们一般会怎么想呢?
May Be
- 首先我们重写 onTouchEvent 方法
- 当第一次点击后,咱们先判断是否为需要监听的控件
- 如果是则 new 一个线程,开始倒计时(如 1s)
- 如果在这个倒计时的期间,再次调用了点击事件
- 判断成功、发生双击事件⌚️
But
这实在是太复杂了,你又要控制时间,又要判断控件等等等等。所以,我们因该如何解决呢?手势监听的使用
GestureDetector 使用
我的理解是 GestureDetector 是 Android 中,专门用来进行手势监听的一个对象,在他的监听器中,我们通过传入 MotionEvents 对象,就可以在各种事件的回调方法中各种手势进行监测。举个例子: GestureDetector 的 OnGestureListener 就是一种回调方法,就是说在获得了传入的这个 MotionEvents 对象之后,进行了处理,我们通过重写了其中的各种方法(单击事件、双击事件等等),就可以监听到单击,双击,滑动等事件,然后直接在这些方法内部进行处理。
使用方法
- 首先,创建一个 SimpleOnGestureListener 回调方法对象,并对其中各个方法进行重写
- 根据这个 listener 对象,实例化出 GestureDetector 对象
- 对目标控件重写 setOnTouchListener 方法,并在其中调用 detector 对象的 onTouchEvent 方法即可
简单易懂,一分钟搞定
@Override
protected void onResume() {
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return detector.onTouchEvent(event);
}
});
super.onResume();
}
private void iniGestureListener(){
GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDoubleTap(MotionEvent e) {
MyToast.makeToast(GestureDetectorActivity.this, "double click up!");
return super.onDoubleTap(e);
}
detector = new GestureDetector(GestureDetectorActivity.this, listener);
}
运行结果
Looper 注册
如果哪位好奇的老铁,尝试着在线程中创建这个 detector 对象(比如下面这种)。那么运行时就可能出现程序崩溃的情况,这是为什么呢?
new Thread(){
@Override
public void run() {
super.run();
detector = new GestureDetector(GestureDetectorActivity.this, listener);
}
}.start();
其实在 GestureDetector 被实例化时,内部会自动创建一个 Handler 用于处理数据,所以如果你在主线程中创建 GestureDetector,那么这个 GestureDetector 内部创建的 Handler 会自动获得主线程的 Looper。也是因此:如果你在一个没有创建 Looper 的子线程中创建 GestureDetector 则需要传递一个带有 Looper 的 Handler 给它,否则就会因为无法获取到 Looper 导致创建失败。
解决
既然问题出现了,那要怎么解决呢。既然是缺少活动中的 Looper ,那么将活动中的 Looper 传入就是。观察 detector 的构造方法,发现其一共有种方法,其中我们常用的方法有两种,首先是