上篇对View做了简单的介绍,这篇对触摸事件做个简单的了解吧。

MotionEvent和TouchSlop

1.MotionEvnet
在手指接触屏幕后所产生的一系列事件中,典型的事件类型有如下几种:

  • ACTION_DOWN ——手指刚接触屏幕;
  • ACTION_MOVE ——手指在屏幕上移动;
  • ACTION_UP —— 手指从屏幕松开的一瞬间;

正常情况下,一次手指触摸屏幕的行为会触发一系列点击事件,考虑如下几种情况:

  • 点击屏幕后离开松开,事件序列为DOWN_UP;
  • 点击屏幕滑动一会在松开,事件序列为DOWN_MOVE…MOVE_UP 。

上述三种情况是典型的事件序列,同时通过MotionEvent对象我们可以得到点击事件发生的x和y坐标。为此,系统提供了两组方法:getX/getY 和getRawX和getRawY。它们的区别其实很简单,getX/getY返回的是相对当前View左上角的 x 和 y 坐标,而getRawX和getRawY返回的是相对于手机屏幕左上角的 x 和 y 坐标。

TouchSlop

TouchSlop 是系统所能识别出的被认为是滑动的最小距离,换句话说,当手指在屏幕上滑动时,如果两次滑动之间的距离小于这个常量,那么系统就不认为你是在进行滑动操作。原因很简单:滑动的距离太短,系统不认为他是滑动。这是一个常量,和设备有关,在不同设备上这个值可能是不同的,通过如下方式即可获取折合常量:

ViewConfiguration.get(getContext()).getScaledTouchSlop();

这个常量是有什么意义呢,当我们在处理滑动时,可以利用这个常量来做一些过滤,比如当两次滑动事件的滑动距离小于这个值,我们就可以认为未达到滑动距离的临界值,因此就可以认为它们不是滑动,这样做就可以有更好的用户体验。其实如果细心的话,可以在源码中找到这个常量的定义,在fragmentworks/base/core/res/res/values/config.xml文件中,如下所示。这个“config_viewConfigurationTouchSlop”对应的就是这个常量的定义。

VeloctiyTracker 、GestureDetector 和 Scroller

VeloctiyTracker 速度追踪,用于追踪手指在滑动过程中的数度,包括水平和竖值方向的速度。它的使用过程很简单,首先,在View的onTouchEvent方法中追踪当前单击事件的速度:

VelocityTracker veloctityTracker=VelocityTracker.obtain();
veloctityTracker.addMovement(event);

接着,当我们先知道当前的滑动速度时,这个时候可以采用如下方式来获得当前的速度:

veloctityTracker.computeCurrentVelocity(1000);
int xVelocity=(int) velocityTracker.getXVelocitx();
int yVelocity=(int) velocityTracker.getXVelocity();

在这一步中有两点需要注意,第一点,获取速度之前必须先计算速度,即getXVelocity 和 getYVeloity 这两个方法的前面必须要调用computeCurrentVelocity方法;第二点,这里的速度是指一段时间内手指所滑动的像素数,比如将时间间隔设为1000ms时,在1s内,手指在水平方向从左向右滑过100像素,那么水平速度就是100。注意速度可以为负数,当手指从右向左滑动时,水平速度即为负值,这个需要理解一下。速度的计算可以用如下公式:

速度 = (终点位置 - 起点位置)/时间段

根据上面的公式,再加上Android系统的坐标系,可以知道,手指逆着坐标系的正方向滑动,所产生的速度即为负值。另外,computeCurrentVelocity这个方法的参数表示的是一个时间单元或者说时间间隔,它的单位是ms,计算速度时得到的速度就是在这个时间间隔内手指在水平或竖值方向上所滑动的像素数,针对上面的例子,如果我们通过veloctityTracker.computeCurrentVeloity(100)来获取速度,那么得到的速度就是手指在100ms内所滑动的像素数,因此水平速度就成了10像素/每100ms(这里假设滑动过程是匀速的),即水平速度为10,这点需要好好理解下。
最后,当不需要使用它的时候,需要调用clear方法来重置并回收内存。

veloctityTracker.clear();
veloctityTracker.recycle();

上面就是如何使用VelocityTracker对象的全过程,看起来并不复杂。