Android View事件基础(二)

字数 709阅读 166

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();

有几点需要注意:

  1. 每次 获取速度前都需要进行速度计算,通过调用computeCurrentVelocity方法进行速度计算.
  2. 测量的速度是指在指定的时间内划过的像素数, 比如时间间隔设置为1000, 假如在1000ms向右内划过了 100像素,那么速度就是100. 可以看出其本质就是测量在给定的时间内移动的像素数.
  3. 同时速度可能是负值, 比如向左移动/向上移动都是负值.联系Android坐标系,这点非常好理解了.
  4. 速度公式 : 速度 = (终点位置 - 起点位置) / 时间段
  5. 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);
}

推荐阅读更多精彩内容