VelocityTracker的簡單使用

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毫秒)時間單位內運動了多少個像素
floatVelocity表示速率的最大值
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的工作原理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章