VelocityTracker
来源:互联网 发布:linux socket pthread 编辑:程序博客网 时间:2024/05/09 15:51
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; @Override public 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.cppvoid 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; @Override public 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; } }}
0 0
- VelocityTracker
- VelocityTracker
- VelocityTracker
- VelocityTracker
- VelocityTracker
- VelocityTracker
- velocitytracker
- VelocityTracker
- VelocityTracker类
- VelocityTracker 使用
- VelocityTracker类
- VelocityTracker 使用
- VelocityTracker 使用
- VelocityTracker简介
- VelocityTracker 使用
- VelocityTracker 使用
- VelocityTracker 使用
- VelocityTracker简介
- java数组学习总结
- Tomcat的session管理探究
- 349. Intersection of Two Arrays
- 构建数据库
- BZOJ 1003 物流运输(最短路+dp)
- VelocityTracker
- 有向图基础
- greenDAO
- BFS的模板程序
- iOS---获取设备各种信息
- JavaScript实现一个简易的计算器
- 亚马逊注册卖家和个人卖家的区别——跨海汇
- PyCharm设置断点,调试(五)
- linux命令-1