MotionEvent
用户触摸手机屏幕后会产生一系列的事件,几个典型的事件如下:
- ACTION_DOWN : 手指刚接触屏幕的一瞬间.
- ACTION_MOVE : 手指按下后在屏幕上移动.
- ACTION_UP : 手指从屏幕上离开的一瞬间.
事件一般不会单独存在, 都是以一个事件序列的形式存在的.比如,手机按下后就会有离开的时候.常见的事件序列如下:
- 点击屏幕后松开(不滑动) :
DOWN --> UP
. - 点击屏幕,在屏幕上滑动,松开:
DWON --> MOVE...MOVE --> UP
既然是在屏幕上操作,那么一定会有相关的位置信息.Android系统为我们提供了两组方法获取位置信息:
-
getX()/getY()
: 获取以当前View左上角为坐标原点的X,Y坐标值. -
getRawX()/getRawY()
: 以手机屏幕左上角,为坐标原点的,x和y值.
TouchSlop
TouchSlop 是系统认为进行了滑动操作的最小距离, 也就是说如果滑动距离小于这个距离, 则则系统认为没有进行滑动操作.它定义在frameworks/base/core/res/values/config.xml
中.
<!-- Base "touch slop" value used by ViewConfiguration as a
movement threshold where scrolling should begin. -->
<dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
从源码中我们可以到他的单位是 dp 也就是说不同像素密度的设备上他的值是不一样的.
同时我们也可以通过代码获取到他的值
ViewConfiguration.get(context).getScaledTouchSlop()
在实际开发中我们可以获取该常量来进行一些过滤操作, 以此达到更好的用户体验效果.
VelocityTracker
速度追踪(VelocityTracker) 用于计算在手指滑动过程中速度. 包括水平方向,竖直方向的速度.使用步骤如下 :
- 添加要追踪的点击事件. 在
onTouchEvent
方法中.
// 获取速度追踪对象
VelocityTracker vt = VelocityTracker.obtain();
// 添加事件.
vt.addMovement(event);
- 获取当前移动速度
// 计算速度. 每次获取速度前都需要调用这个方法.
// 方法参数是时间单位,ms 1000ms 内经过的像素数据.
vt.computeCurrentVelocity(1000);
// 获取速度
int vX = (int) vt.getXVelocity();
int vY = (int) vt.getYVelocity();
有几点需要注意:
- 每次 获取速度前都需要进行速度计算,通过调用computeCurrentVelocity方法进行速度计算.
- 测量的速度是指在指定的时间内划过的像素数, 比如时间间隔设置为1000, 假如在1000ms向右内划过了 100像素,那么速度就是100. 可以看出其本质就是测量在给定的时间内移动的像素数.
- 同时速度可能是负值, 比如向左移动/向上移动都是负值.联系Android坐标系,这点非常好理解了.
- 速度公式 :
速度 = (终点位置 - 起点位置) / 时间段
-
computeCurrentVelocity
的参数就相当于是指定了时间单位. 比如:设置为 100, 那么速度就成了 10 .他是在100ms经过的像素数就是速度, 10像素/100ms. 这个有点别扭,但是只要是记住指定的是时间单位就行了.
- 当不使用时释放资源
vt.clear();
vt.recycle();
**完整使用代码 : **
@Override
public boolean onTouchEvent(MotionEvent event) {
// 第一步 : 将事件添加到速度跟踪中.
VelocityTracker vt = VelocityTracker.obtain();
vt.addMovement(event);
// 第二步 : 获取当前速度.
// 计算速度. 每次获取速度前都需要调用这个方法.
// 方法参数是时间单位,ms 1000ms 内经过的像素数据.
vt.computeCurrentVelocity(1000);
// 获取速度
int vX = (int) vt.getXVelocity();
int vY = (int) vt.getYVelocity();
Log.d(TAG, "onTouchEvent vX : " + vX);
Log.d(TAG, "onTouchEvent vY : " + vY);
// 第三步 : 不使用时释放资源.
vt.clear();
vt.recycle();
return super.onTouchEvent(event);
}