VelocityTracker是android提供的用来记录滑动速度的一个类,可以监控手指移动的速度。

基本用法

如果我们想监控一个view内,手指移动的瞬时速度,该如何做?代码如下所示。主要是在onTouchEvent里记录各个MotionEvent,down事件是起点,此时需要初始化mVelocityTracker(obtain或者reset),第一次肯定是obtain。然后把当前的event记录起来(addMovement)。接着在move的时候获取速度,获取速度用mVelocityTracker.getXVelocity()或者mVelocityTracker.getYVelocity()。在调用这个之前必须做一次计算,也就是mVelocityTracker.computeCurrentVelocity(1000);

最后在up的时候要对mVelocityTracker进行recycle。很简单吧。

public class XView extends View {private static final String DEBUG_TAG = "Velocity";private VelocityTracker mVelocityTracker = null;@Overridepublic boolean onTouchEvent(MotionEvent event) {int index = event.getActionIndex();int action = event.getActionMasked();switch(action) {case MotionEvent.ACTION_DOWN:if(mVelocityTracker == null) {// Retrieve a new VelocityTracker object to watch the velocity of a motion.mVelocityTracker = VelocityTracker.obtain();}else {// Reset the velocity tracker back to its initial state.mVelocityTracker.clear();}// Add a user's movement to the tracker.mVelocityTracker.addMovement(event);break;case MotionEvent.ACTION_MOVE:mVelocityTracker.addMovement(event);// When you want to determine the velocity, call // computeCurrentVelocity(). Then call getXVelocity() // and getYVelocity() to retrieve the velocity for each pointer ID. mVelocityTracker.computeCurrentVelocity(1000);// Log velocity of pixels per second// Best practice to use VelocityTrackerCompat where possible.Log.d("", "X velocity: " +mVelocityTracker.getXVelocity());Log.d("", "Y velocity: " +mVelocityTracker.getYVelocity());break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:// Return a VelocityTracker object back to be re-used by others.mVelocityTracker.recycle();break;}return true;}
}

computeCurrentVelocity

我们看下computeCurrentVelocity这个函数,有2个重载
  public void computeCurrentVelocity(int units) {nativeComputeCurrentVelocity(mPtr, units, Float.MAX_VALUE);}public void computeCurrentVelocity(int units, float maxVelocity) {nativeComputeCurrentVelocity(mPtr, units, maxVelocity);}

我们刚才用的是第一种方法,传了个1000.这个表示计算过去1000ms(即1s)内的速度。这个速度其实就是 ((当前的位置)-(之前的位置))/时间.如果得到的值为200就表示这1000ms内,X方向移动了200像素。
    速度是有正负的,右划就是正的,左划就是负的,上划为负,下划为正。
    最大速度传的是Float的最大值,第二种方法可以指定最大速度。这个最大速度有什么用呢?
    实际上是一个上限,比如我们当前速度300,但是上限为200,那用getXVelocity()得到的值就是200,不可能超过上限(无论正负),相关代码如下所示。

    //android_view_VelocityTracker.cpp
void VelocityTrackerState::computeCurrentVelocity(int32_t units, float maxVelocity) {BitSet32 idBits(mVelocityTracker.getCurrentPointerIdBits());mCalculatedIdBits = idBits;for (uint32_t index = 0; !idBits.isEmpty(); index++) {uint32_t id = idBits.clearFirstMarkedBit();float vx, vy;mVelocityTracker.getVelocity(id, &vx, &vy);vx = vx * units / 1000;vy = vy * units / 1000;if (vx > maxVelocity) {vx = maxVelocity;} else if (vx < -maxVelocity) {vx = -maxVelocity;}if (vy > maxVelocity) {vy = maxVelocity;} else if (vy < -maxVelocity) {vy = -maxVelocity;}Velocity& velocity = mCalculatedVelocity[index];velocity.vx = vx;velocity.vy = vy;}
}

惯性滑动

还有个比较常见的需求,比如我们右划了一下,view往右移动,我们希望在手指抬起来之后,view能够按照惯性继续滑动一段距离然后停止,此时就需要手指抬起的时候的速度,可以在up的时候计算。

模板写法

我查了下网上的资料,发现不同的人有不同的写法,有点茫然,不知道该参考谁,本文的例子主要从android官方demo和源码内提取出来,应该没有坑,下次有需求,抄这段代码比较合适.这个写法和前文 基本用法里的有点区别,都是靠谱的,这里没有用到clear,每次都是obtain,然后recycle。基本用法里多了个clear,按道理提高了重用性,性能会好一些。但是我看了下ScrollView和ViewPager都是按照下边的写法来的,估计他们写的也比较随意。
public class XView extends View {private static final String DEBUG_TAG = "Velocity";private static final int V_CONSTANT=50;private VelocityTracker mVelocityTracker = null;@Overridepublic boolean onTouchEvent(MotionEvent event) {int index = event.getActionIndex();int action = event.getActionMasked();initVelocityTrackerIfNotExists();switch(action) {case MotionEvent.ACTION_DOWN:if(mVelocityTracker == null) {// Retrieve a new VelocityTracker object to watch the velocity of a motion.mVelocityTracker = VelocityTracker.obtain();}else {// Reset the velocity tracker back to its initial state.mVelocityTracker.clear();}// Add a user's movement to the tracker.mVelocityTracker.addMovement(event);break;case MotionEvent.ACTION_MOVE:mVelocityTracker.addMovement(event);break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000);int initialVelocity = (int) velocityTracker.getYVelocity();if ((Math.abs(initialVelocity) > V_CONSTANT)) {//速度够大,就做什么事,比如翻页,some是个常数,大约在30-100之间
//                    ...} else{
//                    ...}recycleVelocityTracker();break;}return true;}private void initVelocityTrackerIfNotExists() {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}}private void recycleVelocityTracker() {if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;}}
}

VelocityTracker相关推荐

  1. 代码解说Android Scroller、VelocityTracker

    在编写自己定义滑动控件时经常会用到Android触摸机制和Scroller及VelocityTracker.Android Touch系统简单介绍(二):实例具体解释onInterceptTouchE ...

  2. VelocityTracker简单介绍

    翻译自:http://developer.android.com/reference/android/view/VelocityTracker.html 參照自: http://blog.jrj.co ...

  3. VelocityTracker简要

    翻译自:http://developer.android.com/reference/android/view/VelocityTracker.html 參照自: http://blog.jrj.co ...

  4. 滑轮控件研究四、VelocityTracker的简单研究

    帮助你追踪一个touch事件(flinging事件和其他手势事件)的速率.当你要跟踪一个touch事件的时候,使用obtain()方法得到这个类的实例,然后 用addMovement(MotionEv ...

  5. android.view.VelocityTracker

    顾名思义即速率跟踪者,主要用来跟踪触摸事件(flinging和getsture)的速率,在UI特效的设计上非常有用. 使用时: step1:通过VelocityTracker.obtain()方法实例 ...

  6. 速度追踪--VelocityTracker

    概述 我们都知道安卓手机的事件分为两类,一类是按键事件,另一类就是屏幕滑动事件,而我们大部分的事件都是通过屏幕滑动来产生的.在滑动的过程中你有没有想过要求一下手指在屏幕上滑动的速度呢!我们可以在滑动事 ...

  7. 关于Android滑动scroll,弹性滑动以及VelocityTracker

    一 VelocityTracker 速度追踪,手指在滑动中的速度,包括水平和竖直方向. 计算公式: 速度 =(终点位置-起点位置)/ 时间段 使用: VelocityTracker velocityT ...

  8. scrollTo与scrollBy用法以及TouchSlop与VelocityTracker解析

    下一篇: scroller类的用法完全解析以及带源码分析 最近在工作中使用到了scrollTo与scrollBy,因此在这准备对它们的用法以及TouchSlop与VelocityTracker做一下整 ...

  9. VelocityTracker的简单使用

    VelocityTracker顾名思义即速度跟踪,在android中主要应用于touch even.VelocityTracker通过跟踪一连串事件实时计算出当前的速度,这样的用法在android系统 ...

  10. Android 获取控件滑动速度,速度跟踪器VelocityTracker;

    VelocityTracker 速度跟踪器 在写关于Android滑动的控件,如果用户手指在屏幕上(当前位置 - 起始位置 > 某个数值)就做一个界面切换,但是总感觉太生硬,只有满足上面的条件才 ...

最新文章

  1. Spring官宣新家族成员:Spring Authorization Server!
  2. pyhon简单比较文本相似度的方法
  3. 成功解决TypeError: __init__() got an unexpected keyword argument 'serialized_options'
  4. 进程线程002 等待链表 调度链表
  5. U盘安装Ubuntu三步走
  6. poj2823 Sliding Window
  7. 2013年28周信息安全汇总(7.7 - 7.13)
  8. python基本函数归整
  9. Qt之HTTP之模仿迅雷——根据URL获取文件信息(上)
  10. 随机邻域嵌入_[读综述] 图嵌入的应用
  11. 红外条码扫描器的另类使用C#版
  12. 用友nc java_用友NC系统使用过程中常见问题和解决方法!收藏!
  13. 数据库的设计及经典案例
  14. Pyrene-PEG-Acid,芘丁酸聚乙二醇羧基,Pyrene-PEG-COOH
  15. Exif 格式介绍和操作
  16. 手机浏览器devtools_浏览器DevTools的秘诀:启动,网络和性能
  17. LBS-----基站轨迹定位算法
  18. Markdown学习(入门级)
  19. 站稳前三之后,新华三大数据亮剑三大新能力
  20. 10Gb每秒!SM4的单核“心”!海泰携手海量数据安全“闪”护

热门文章

  1. stm32Cubemx USB虚拟串口
  2. 电脑win7支持的node.js版本
  3. YYLabel的若干个疑问持续更新
  4. 安装企业级的dokuwiki文档系统
  5. 二叉树非递归遍历(先序、中序、后序)(C++)
  6. 如何录制电脑内部声音
  7. dwg格式的计算机图,例举电脑dwg文件怎么打开
  8. 航迹推演(Odometry)
  9. Matlab实现图像识别(四)
  10. C/C++:std::thread构造函数死锁问题:WIN32下不可以在DllMain中创建线程