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()獲得橫向和豎向的速率。
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的工作原理。