🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
#### 3.1.4 VelocityTracker、GestureDetector和Scroller **1.VeIocityTracker** 速度追踪,用于追踪手指在滑动过程中的速度,包括水平和竖直方向的速度。它的使用过程很简单,首先,在View的onTouchEvent方法中追踪当前单击事件的速度: VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event); 接着,当我们先知道当前的滑动速度时,这个时候可以采用如下方式来获得当前的速度: velocityTracker.computeCurrentVelocity(1000); int xVelocity = (int) velocityTracker.getXVelocity(); int yVelocity = (int) velocityTracker.getYVelocity(); 在这一步中有两点需要注意,第一点,获取速度之前必须先计算速度,即getXVelocity和getYVelocity这两个方法的前面必须要调用computeCurrentVelocity方法;第二点,这里的速度是指一段时间内手指所滑过的像素数,比如将时间间隔设为1000ms时,在1s内,手指在水平方向从左向右滑过100像素,那么水平速度就是100。注意速度可以为负数,当手指从右往左滑动时,水平方向速度即为负值,这个需要理解一下。速度的计算可以用如下公式来表示: 速度 =(终点位置 - 起点位置)/ 时间段 根据上面的公式再加上Android系统的坐标系,可以知道,手指逆着坐标系的正方向滑动,所产生的速度就为负值。另外,computeCurrentVelocity这个方法的参数表示的是一个时间单元或者说时间间隔,它的单位是毫秒(ms),计算速度时得到的速度就是在这个时间间隔内手指在水平或竖直方向上所滑动的像素数。针对上面的例子,如果我们通过velocityTracker.computeCurrentVelocity(100)来获取速度,那么得到的速度就是手指在100ms内所滑过的像素数,因此水平速度就成了10像素/每100ms(这里假设滑动过程是匀速的),即水平速度为10,这点需要好好理解一下。 最后,当不需要使用它的时候,需要调用clear方法来重置并回收内存: velocityTracker.clear(); velocityTracker.recycle(); 上面就是如何使用VelocityTracker对象的全过程,看起来并不复杂。 **2.GestureDetector** 手势检测,用于辅助检测用户的单击、滑动、长按、双击等行为。要使用GestureDetector也不复杂,参考如下过程。 首先,需要创建一个GestureDetector对象并实现OnGestureListener接口,根据需要我们还可以实现OnDoubleTapListener从而能够监听双击行为: GestureDetector mGestureDetector = new GestureDetector(this); //解决长按屏幕后无法拖动的现象 mGestureDetector.setIsLongpressEnabled(false); 接着,接管目标View的onTouchEvent方法,在待监听View的onTouchEvent方法中添加如下实现: boolean consume = mGestureDetector.onTouchEvent(event); return consume; 做完了上面两步,我们就可以有选择地实现OnGestureListener和OnDoubleTapListener中的方法了,这两个接口中的方法介绍如表3-1所示。 表3-1 OnGestureListener和OnDoubleTapListener中的方法介绍 ![](https://img.kancloud.cn/eb/ae/ebae579a9ce70fae629ad4d1e6c48518_991x622.png) 表3-1里面的方法很多,但是并不是所有的方法都会被时常用到,在日常开发中,比较常用的有:onSingleTapUp(单击)、 onFling(快速滑动)、onScroll(拖动)、onLongPress(长按)和onDoubleTap(双击)。另外这里要说明的是,实际开发中,可以不使用GestureDetector,完全可以自己在View的onTouchEvent方法中实现所需的监听,这个就看个人的喜好了。这里有一个建议供读者参考:如果只是监听滑动相关的,建议自己在onTouchEvent中实现,如果要监听双击这种行为的话,那么就使用GestureDetector。 **3.ScroIIer** 弹性滑动对象,用于实现View的弹性滑动。我们知道,当使用View的scrollTo/scrollBy方法来进行滑动时,其过程是瞬间完成的,这个没有过渡效果的滑动用户体验不好。这个时候就可以使用Scroller来实现有过渡效果的滑动,其过程不是瞬间完成的,而是在一定的时间间隔内完成的。Scroller本身无法让View弹性滑动,它需要和View的computeScroll方法配合使用才能共同完成这个功能。那么如何使用Scroller呢?它的典型代码是固定的,如下所示。至于它为什么能实现弹性滑动,这个在3.2节中会进行详细介绍。 Scroller scroller = new Scroller(mContext); // 缓慢滚动到指定位置 private void smoothScrollTo(int destX, int destY) { int scrollX = getScrollX(); int delta = destX - scrollX; // 1000ms内滑向destX,效果就是慢慢滑动 mScroller.startScroll(scrollX, 0, delta, 0, 1000); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } }