滑动速度跟踪类VelocityTracker介绍

VelocityTracker 是一个跟踪触摸事件滑动速度的帮助类,用于实现flinging以及其它类似的手势。它的原理是把触摸事件 MotionEvent 对象传递给VelocityTracker的addMovement(MotionEvent)方法,然后分析MotionEvent 对象在单位时间类发生的位移来计算速度。你可以使用getXVelocity() 或getXVelocity()获得横向和竖向的速率到速率时,但是使用它们之前请先调用computeCurrentVelocity(int)来初始化速率的单位 。

主要函数

Public Methods
void
Add a user's movement to the tracker.

| | void | clear()

Reset the velocity tracker back to its initial state.

| | void | [computeCurrentVelocity](http://developer.android.com/reference/android/view/VelocityTracker.html#computeCurrentVelocity(int, float))(int units, float maxVelocity)

Compute the current velocity based on the points that have been collected.

intunitis表示速率的基本时间单位。unitis值为1的表示是,一毫秒时间单位内运动了多少个像素, unitis值为1000表示一秒(1000毫秒)时间单位内运动了多少个像素

floatVelocity表示速率的最大值

| | void | computeCurrentVelocity(int units)

Equivalent to invoking [computeCurrentVelocity(int, float)](http://developer.android.com/reference/android/view/VelocityTracker.html#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) |

示例:

private VelocityTracker mVelocityTracker;//生命变量  
//在onTouchEvent(MotionEvent ev)中  
if (mVelocityTracker == null) {  
    mVelocityTracker = VelocityTracker.obtain();//获得VelocityTracker类实例  
}  
mVelocityTracker.addMovement(ev);//将事件加入到VelocityTracker类实例中  
//判断当ev事件是MotionEvent.ACTION_UP时:计算速率  
final VelocityTracker velocityTracker = mVelocityTracker;  
// 1000 provides pixels per second  
velocityTracker.computeCurrentVelocity(1, (float)0.01);//设置maxVelocity值为0.1时,速率大于0.01时,显示的速率都是0.01,速率小于0.01时,显示正常  
Log.i("test","velocityTraker"+velocityTracker.getXVelocity());  
velocityTracker.computeCurrentVelocity(1000); //设置units的值为1000,意思为一秒时间内运动了多少个像素  
Log.i("test","velocityTraker"+velocityTracker.getXVelocity());

大体的使用是这样的:

当你需要跟踪触摸屏事件的速度的时候,使用obtain()方法来获得VelocityTracker类的一个实例对象

在onTouchEvent回调函数中,使用addMovement(MotionEvent)函数将当前的移动事件传递给VelocityTracker对象

使用computeCurrentVelocity (int units)函数来计算当前的速度,使用getXVelocity ()、 getYVelocity ()函数来获得当前的速度

下面是一个简单Demo: 

package com.bxwu.demo.component.activity; 
import android.app.Activity; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.view.MotionEvent; 
import android.view.VelocityTracker; 
import android.view.ViewConfiguration; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.TextView; 
  
public class VelocityTrackerTest extends Activity { 
    private TextView mInfo; 
  
    private VelocityTracker mVelocityTracker; 
    private int mMaxVelocity; 
  
    private int mPointerId; 
  
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        
        mVelocityTracker = VelocityTracker.obtain(); 
        mMaxVelocity = ViewConfiguration.get(this).getMaximumFlingVelocity();     
            
        mInfo = new TextView(this); 
        mInfo.setLines(4); 
        mInfo.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
        mInfo.setTextColor(Color.WHITE); 
        setContentView(mInfo); 
    } 
  
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
        final int action = event.getAction(); 
        
        mVelocityTracker.addMovement(event); 
        
        final VelocityTracker verTracker = mVelocityTracker; 
        switch (action) { 
            case MotionEvent.ACTION_DOWN: 
                //求第一个触点的id, 此时可能有多个触点,但至少一个 
                mPointerId = event.getPointerId(0); 
                break; 
  
            case MotionEvent.ACTION_MOVE: 
                //求伪瞬时速度 
                verTracker.computeCurrentVelocity(1000, mMaxVelocity); 
                final float velocityX = verTracker.getXVelocity(mPointerId); 
                final float velocityY = verTracker.getYVelocity(mPointerId); 
                recodeInfo(velocityX, velocityY); 
                break; 
  
            case MotionEvent.ACTION_UP: 
                releaseVelocityTracker(); 
                break; 
  
            case MotionEvent.ACTION_CANCEL: 
                releaseVelocityTracker(); 
                break; 
  
            default: 
                break; 
        } 
        return super.onTouchEvent(event); 
    } 
    //释放VelocityTracker 
    private void releaseVelocityTracker() { 
        if(null != mVelocityTracker) { 
            mVelocityTracker.clear(); 
            mVelocityTracker.recycle(); 
            mVelocityTracker = null; 
        } 
    } 
  
    private static final String sFormatStr = "velocityX=%f\\nvelocityY=%f"; 
  
    /** 
     * 记录当前速度 
     * 
     * @param velocityX x轴速度 
     * @param velocityY y轴速度 
     */
    private void recodeInfo(final float velocityX, final float velocityY) { 
        final String info = String.format(sFormatStr, velocityX, velocityY); 
        mInfo.setText(info); 
    } 
}

代码很简单,我们可以求出move过程中的伪瞬时速度, 这样在做很多控件的时候都是可以用到的,比如系统Launcher的分页,

ScrollView滑动等, 可根据此时的速度来计算ACTION_UP后的减速运动等。实现一些非常棒的效果。