您的位置:首页 > 移动开发 > Android开发

Android小总结:VelocityTracker

2014-12-25 11:45 232 查看
VelocityTracker是一个什么东西呢,查看VelocityTracker源代码发现有如下注释:

/**
* Helper for tracking the velocity of touch events, for implementing
* flinging and other such gestures.
*
* Use {@link #obtain} to retrieve a new instance of the class when you are going
* to begin tracking.  Put the motion events you receive into it with
* {@link #addMovement(android.view.MotionEvent)}.  When you want to determine the velocity call
* {@link #computeCurrentVelocity(int)} and then call {@link #getXVelocity(int)}
* and {@link #getYVelocity(int)} to retrieve the velocity for each pointer id.
*
* 追踪触摸事件速率,实现flinging和其他手势的帮助类
*
* 1、当开始追踪的时候,使用obtain来获取VelocityTracker类的实例
* 2、把接收到的MotionEvent放入到addMovement(android.view.MotionEvent)中
* 3、当要确定速度时调用computeCurrentVelocity(int),
*   使用getXVelocity(int)和getYVelocity(int)来检测每个触摸点id的速率
*/


VelocityTracker是一个帮助追踪触摸事件速率的追踪器,可以追踪fliinging和其他触摸手势。

如何使用VelocityTracker呢,注释中提到如下步骤:

1、当开始追踪的时候,使用obtain来获取VelocityTracker类的实例
2、把接受到的MotionEvent放入到addMovement(android.view.MotionEvent)中
3、当要确定速度时调用computeCurrentVelocity(int),
使用getXVelocity(int)和getYVelocity(int)来检测每个触摸点id的速率


既然VelocityTracker是追踪触摸事件的速度追踪器,当然需要与触摸事件结合使用。

第一步:当你想要追踪触摸事件的速度时,使用private VelocityTracker mVelocityTracker = VelocityTracker.obtain();来获取一个实例,

obtain()方法的源代码:

/**
* Retrieve a new VelocityTracker object to watch the velocity of a
* motion.  Be sure to call {@link #recycle} when done.  You should
* generally only maintain an active object while tracking a movement,
* so that the VelocityTracker can be re-used elsewhere.
*
* @return Returns a new VelocityTracker.
*
* 获取一个新的VelocityTracker对象,用于检测一个动作的速率
* 检测结束时确保调用了recycle()方法来回收VelocityTracker对象
* 追踪一个移动事件时通常只需要维护一个活动对象,这样VelocityTracker可以被重用
*/
static public VelocityTracker obtain() {
VelocityTracker instance = sPool.acquire();
return (instance != null) ? instance : new VelocityTracker(null);
}


第二步:把接收到的MotionEvent放入到addMovement(MotionEvent event)方法中,

在初始化MotionEvent的ACTION_DOWN时调用addMovement(MotionEvent event)

然后在ACTION_MOVE和ACTION_UP动作中就可以检测到速度了。

/**
* Add a user's movement to the tracker.  You should call this for the
* initial {@link MotionEvent#ACTION_DOWN}, the following
* {@link MotionEvent#ACTION_MOVE} events that you receive, and the
* final {@link MotionEvent#ACTION_UP}.  You can, however, call this
* for whichever events you desire.
*
* @param event The MotionEvent you received and would like to track.
*
* 添加一个移动事件到追踪器
* 1.为初始化MotionEvent的ACTION_DOWN动作调用addMovement()
* 2.接下来,在MotionEvent的ACTION_MOVE和ACTION_UP动作中接收。
*    不管是哪一个events都可以调用本方法
*/
public void addMovement(MotionEvent event) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
nativeAddMovement(mPtr, event);
}


第三步:想要确定速度的时候调用computeCurrentVelocity(int units)方法。有两个同样的方法,一个带有最大值参数,默认为Float.MAX_VALUE

/**
* Compute the current velocity based on the points that have been
* collected.  Only call this when you actually want to retrieve velocity
* information, as it is relatively expensive.  You can then retrieve
* the velocity with {@link #getXVelocity()} and
* {@link #getYVelocity()}.
* 根据收集到的触摸点计算当前速率
* 因为此方法相当消耗性能,所以只有当真的确实想要检测速度信息的时候才调用这个方法
* 然后可以通过getXVelocity()和getYVelocity()方法获取到追踪的速度
*
* @param units The units you would like the velocity in.  A value of 1
* provides pixels per millisecond, 1000 provides pixels per second, etc.
*        units :代表速度的单位,
*              值为1时:代表每毫秒运动一个像素,px/ms
*              值为1000时:代表每秒运动1000个像素,1000px/s
* @param maxVelocity The maximum velocity that can be computed by this method.
* This value must be declared in the same unit as the units parameter. This value
* must be positive.
*        maxVelocity :代表可以被本方法计算的最大速度,
*                    这个值必须用同一个作为速度参数的单位声明,而且值必须为正数
*/
public void computeCurrentVelocity(int units, float maxVelocity) {
nativeComputeCurrentVelocity(mPtr, units, maxVelocity);
}


/**
* Equivalent to invoking {@link #computeCurrentVelocity(int, float)} with a maximum
* velocity of Float.MAX_VALUE.
*
* @see #computeCurrentVelocity(int, float)
*
* 等价调用带有最大值为Float.MAX_VALUE的computeCurrentVelocity(int, float)方法,
*/
public void computeCurrentVelocity(int units) {
nativeComputeCurrentVelocity(mPtr, units, Float.MAX_VALUE);
}


第四步:使用getXVelocity()和getYVelocity()方法获取检测到的速度

获取X轴方向的速度:

/**
* Retrieve the last computed X velocity.  You must first call
* {@link #computeCurrentVelocity(int)} before calling this function.
*
* 检测最后计算的X轴方向的速度,在调用getXVelocity()之前必须先调用computeCurrentVelocity(int)
* @return The previously computed X velocity.
*/
public float getXVelocity() {
return nativeGetXVelocity(mPtr, ACTIVE_POINTER_ID);
}
获取Y轴方向上的速度:
/**
* Retrieve the last computed Y velocity.  You must first call
* {@link #computeCurrentVelocity(int)} before calling this function.
*
* 检测最后计算的X轴方向的速度,在调用getXVelocity()之前必须先调用computeCurrentVelocity(int)
* @return The previously computed Y velocity.
*/
public float getYVelocity() {
return nativeGetYVelocity(mPtr, ACTIVE_POINTER_ID);
}


第五步:回收VelocityTracker实例

/**
* Return a VelocityTracker object back to be re-used by others.  You must
* not touch the object after calling this function.
*
* 回收一个VelocityTracker对象给其他动作事件使用
* 在调用recycle()这个函数之后,你不能访问VelocityTracker对象
*/
public void recycle() {
if (mStrategy == null) {
clear();
sPool.release(this);
}
}


小实例:

package com.zwc.admin.scrollerdemo;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;

public class VelocityTrackerTestActivity extends ActionBarActivity {

private static final String TAG = "VelocityTrackerTestActivity";

private VelocityTracker mVelocityTracker;
private int mPointerId;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_velocity_tracker_test);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (null == mVelocityTracker) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);

switch (action) {
case MotionEvent.ACTION_DOWN:
//获取第一个触摸点的id
mPointerId = event.getPointerId(0);
break;

case MotionEvent.ACTION_MOVE:
mVelocityTracker.computeCurrentVelocity(1000);
float xVelocity = mVelocityTracker.getXVelocity(event.getPointerId(mPointerId));
float yVelocity = mVelocityTracker.getYVelocity(event.getPointerId(mPointerId));
Log.e(TAG, "xVelocity = " + xVelocity + ",yVelocity = " + yVelocity);
break;

case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
}
break;
}

return super.onTouchEvent(event);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: