VelocityTracker顾名思义即速度跟踪,在android中主要应用于touch even。VelocityTracker通过跟踪一连串事件实时计算出当前的速度,这样的用法在android系统空间中随处可见,比如Gestures中的Fling, Scrolling等。
/**
* 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(MotionEvent)},
* and when you want to determine the velocity call
* {@link #computeCurrentVelocity(int)} and then {@link #getXVelocity()}
* and {@link #getXVelocity()}.
*/
简单翻译下:帮助你追踪一个touch事件(flinging事件和其他手势事件)的速率。当你要跟踪一个touch事件的时候,使用obtain()方法得到这个类的实例,然后 用addMovement(MotionEvent)函数将你接受到的motion event加入到VelocityTracker类实例中。当你使用到速率时,使用computeCurrentVelocity(int)初始化速率的单位,并获得当前的事件的速率,然后使用getXVelocity() 或getXVelocity()获得横向和竖向的速率。
Velocity Tracker主要包括的函数如下:
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
addMovement(
MotionEvent event)
Add a user's movement to the tracker.
| ||||||||||
void |
clear()
Reset the velocity tracker back to its initial state.
| ||||||||||
void |
computeCurrentVelocity(int units, float maxVelocity)
Compute the current velocity based on the points that have been collected.
int
unitis表示速率的基本时间单位。unitis值为
1的表示是,一毫秒时间单位内运动了多少个像素, unitis值为
1000表示一秒(1000毫秒)时间单位内运动了多少个像素
float
Velocity表示速率的最大值
| ||||||||||
void |
computeCurrentVelocity(int units)
Equivalent to invoking
computeCurrentVelocity(int, float) with a maximum velocity of Float.MAX_VALUE.
| ||||||||||
abstract T | getNextPoolable() | ||||||||||
float |
getXVelocity()
Retrieve the last computed X velocity.
| ||||||||||
float |
getXVelocity(int id)
Retrieve the last computed X velocity.
| ||||||||||
float |
getYVelocity(int id)
Retrieve the last computed Y velocity.
| ||||||||||
float |
getYVelocity()
Retrieve the last computed Y velocity.
| ||||||||||
abstract boolean | isPooled() | ||||||||||
static VelocityTracker |
obtain()
Retrieve a new VelocityTracker object to watch the velocity of a motion.
| ||||||||||
void |
recycle()
Return a VelocityTracker object back to be re-used by others.
| ||||||||||
abstract void | setNextPoolable(T element) | ||||||||||
abstract void | setPooled(boolean isPooled) |
从上面的介绍中,我们可以很使用VelocityTracker类去追踪一个移动事件的速率。VelocityTracker的详细使用不走如下:
1.首先获得VelocityTracker的实例
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
2.把事件event,将事件加入到VelocityTracker类实例中
mVelocityTracker.addMovement(event);
3. 判断当事件MotionEvent.ACTION_MOVE的时候,调用下面的方法 ,并获取到x,y方向的速度。
final float velocityX = verTracker.getXVelocity(mPoniterId);
final float velocityY = verTracker.getYVelocity(mPoniterId);
String info = String.format(sFormatStr, velocityX, velocityY);
tv_info.setText(info);
4. 判断当事件MotionEvent.ACTION_UP或者MotionEvent.ACTION_CANCEL的时候释放Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
}
到此Velocity Tracker的基本使用就介绍完毕了,最后附上Demo的源码,进攻参考。
package cn.chinaiptn.velocitytracker;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private VelocityTracker mVelocityTracker;
private int mMaxVelocity;
private int mPoniterId;
private TextView tv_info;
private static final String sFormatStr = "velocityX=%f\nvelocityY=%f";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_info = (TextView) findViewById(R.id.tv_info);
mMaxVelocity = ViewConfiguration.get(MainActivity.this).getMaximumFlingVelocity();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
initVelocityTracker(event);
final VelocityTracker verTracker = mVelocityTracker;
switch (action) {
case MotionEvent.ACTION_DOWN:
//求第一个触点的id, 此时可能有多个触点,但至少一个
mPoniterId = event.getPointerId(0);
break;
case MotionEvent.ACTION_MOVE:
//求伪瞬时速度
verTracker.computeCurrentVelocity(1000, mMaxVelocity);
final float velocityX = verTracker.getXVelocity(mPoniterId);
final float velocityY = verTracker.getYVelocity(mPoniterId);
String info = String.format(sFormatStr, velocityX, velocityY);
tv_info.setText(info);
break;
case MotionEvent.ACTION_UP:
releaseVelocityTracker();
break;
case MotionEvent.ACTION_CANCEL:
releaseVelocityTracker();
break;
default:
break;
}
return super.onTouchEvent(event);
}
/**
* 向mVelocityTracker添加MotionEvent
*
* @param event
*/
private void initVelocityTracker(final MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
}
/**
* 释放VelocityTracker
*/
private void releaseVelocityTracker() {
if (null != mVelocityTracker) {
mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
}
本文主要参考了
http://blog.csdn.net/lonelyroamer/article/details/7560598
下篇博文将从源码的角度去熟悉Velocity Tracker的工作原理。