方案四
和上面几个方法一样,只不过在子线称里提前准备好 Lopper ,这样子线称就和主线程一样了
刚刚我们已经通过双击效果,讲过 onDoubleTapEvent 了,那么 GestureDetecotr 还有哪些厉害的回调方法呢?
OnDoubleTapListener :也就是双击事件,双击事件除了 onDoubleTapEvent 这个回调方法之外,还有 SingleTapConfirmed 和 DoubleTap 这两个回调方法
OnGestureListener :这里集合了众多手势的监听器:主要有:按下(Down)、 扔(Fling)、长按(LongPress)、滚动(Scroll)、触摸反馈(ShowPress) 和 单击抬起(SingleTapUp)
SimpleOnGestureListener :上述接口的空实现,用的频率比较多
OnDoubleTapListener我们先来讲讲 OnDoubleTapListener,大家可能要问:刚刚不是已经讲过双击事件监听了吗,这里又来不是浪费时间?废话不说,让我详细介绍下这类的方法:
单击回调 SingleTapConfirmed有人就会很好奇,对于单击事件的回调,直接去用 onClickListener 不就好了么,干嘛要用 SingleTapConfirmed 呢?
首先,这两个方法是冲突的,这里就涉及到了事件分发机制,这点我后期会专门给大家总结下,这里就不详解了。
其二,更具 onClickListener 的机制,我们不难发现,如果是用 onClickListener 的话,当我们双击时,我们也会调用单击事件,也就是单击了两次,这明显是不符合我们意图的。那么该如何调用呢?very easy !
final GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onSingleTapConfirmed(MotionEvent e) { MyToast.makeToast(GestureDetectorActivity.this, "single click!"); return super.onSingleTapConfirmed(e); } ... }; DoubleTap 与 onDoubleTapEvent我打算把这两个方法放在一起将,一则他两都属于双击的范畴,二则他两有着极高相似和细微却重要的区别。
大家可以尝试着在 onTouchEvent 和 DoubleTap 中,对点击的 Down move 和 up 进行打印,你就会发现,对于 DoubleTap 而言,它是在第二次点击按下是,发生的回调,而对于 onDoubleTapEvent 而言,则是在第二次点击后,手指抬起离开了屏幕时,发生的回调。这就是他两最重要的区别。
final GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onDoubleTap(MotionEvent e) { MyToast.makeToast(GestureDetectorActivity.this, "double click down!"); return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { switch (e.getActionMasked()){ case MotionEvent.ACTION_UP: MyToast.makeToast(GestureDetectorActivity.this, "double click up!"); break; } return super.onDoubleTapEvent(e); } };所以,有了这两个方法,我们就可以更具目的性的满足两种需求。
讲到这里,单击双击事件就告一段落了,下面我们进入 OnGestureListener 的学习
这可以说是整个手势监测中,最核心的部分了,前面都是引入,现在才是正题,这里我主要向大家介绍一下手势:
按下(Down)
一扔(Fling)
长按(LongPress)
滚动(Scroll)
触摸反馈(ShowPress)
单击抬起(SingleTapUp)
onDownonDown 事件很好理解,他在一个 View 被按下时执行。也正是如此,要想能执行 onDown ,首先要保证这个 View 是可以点击的,也就是 onClickable 的值为 true 。
private final GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onDown(MotionEvent e) { MyToast.makeToast(GestureDetectorActivity.this, "onDown"); // 后续事件 return super.onDown(e); } }; onFling对于 onFling 我个人感觉这是个最常用的方法,就像它的名字,翻译过来是拖、拽、扔的意思。举个例子 RecyclerView 或者 ListView 我们都有用过,当我们快速上拉后会滚动一定距离停止,我们可爱的 onFling 就是用于检测这种手势的。
private final GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { mSpeedX = velocityX; mSpeedY = velocityY; handler.postDelayed(runnable, 30); return super.onFling(e1, e2, velocityX, velocityY); } };从代码中,我们不难发现:该方法有四个参数
参数 意义e1 手指按下时的 Event。
e2 手指抬起时的 Event。
velocityX 在 X 轴上的运动速度(像素/秒)。
velocityY 在 Y 轴上的运动速度(像素/秒)。
通过前两个 MotionEvent 参数,我们可以获得点击发生的位置等,通过后两个 float 参数,我们可以获得手指滑动的速度。
具体使用其实还是蛮多的,比如我们可以想象下台球游戏,球杆击球后,就有这样一个初速度递减的效果。
onLongPress