VelocityTracker这个类主要是一个滑动跟踪器,常在touch event里面使用,比较简单,在这里,我们只需要熟练它的几个方法就行了。
直接来看源码方法,源码不多:
/**
* 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.
*/
static public VelocityTracker obtain() {
return sPool.acquire();
}
我们看注释知道,这是当我需要实例化VelocityTracker对象的时候。调用这个方法,并且使用完成后要通过recycle()方法回收。我们应该保证只有一个VelocityTracker实例,所以VelocityTracker是可以重用的。
/**
* Return a VelocityTracker object back to be re-used by others. You must
* not touch the object after calling this function.
*/
public void recycle() {
if (mStrategy == null) {
sPool.release(this);
}
}
使用完后回收方法。
/**
* Reset the velocity tracker back to its initial state.
*/
public void clear() {
nativeClear(mPtr);
}
重置velocity tracker初始化
/**
* 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.
*/
public void addMovement(MotionEvent event) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
nativeAddMovement(mPtr, event);
}
初始化的时候调用传递touch事件给VelocityTracker实例。
/**
* 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()}.
*
* @param units The units you would like the velocity in. A value of 1
* provides pixels per millisecond, 1000 provides pixels per second, etc.
* @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.
*/
public void computeCurrentVelocity(int units, float maxVelocity) {
nativeComputeCurrentVelocity(mPtr, units, maxVelocity);
}
计算当前速度, 其中units是单位表示, 1代表px/毫秒, 1000代表px/秒,
public float getXVelocity();
public float getYVelocity();
public float getXVelocity(int id);
public float getYVelocity(int id);
//经过一次computeCurrentVelocity后你就可以用一下上面方法获取此次计算的值
//id是touch event触摸点的ID, 来为多点触控标识,有这个标识在计算时可以忽略
//其他触点干扰,当然干扰肯定是有的
下面我们通过一个demo来使用下这写方法:
public class VelocityTrackerTest extends Activity{
private VelocityTracker mVelocityTracker;
private int mMaxVelocity;
private TextView mTextInfo;
private int mPointerId;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mTextInfo = new TextView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
mTextInfo.setLayoutParams(params);
mTextInfo.setTextColor(Color.BLACK);
mTextInfo.setBackgroundColor(Color.WHITE);
setContentView(mTextInfo);
mMaxVelocity = ViewConfiguration.get(this).getMaximumFlingVelocity();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
acquireVelocityTracker(event);
final VelocityTracker verTracker = mVelocityTracker;
switch(event.getAction()){
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;
}
return super.onTouchEvent(event);
}
private void acquireVelocityTracker(final MotionEvent event){
if(null == mVelocityTracker) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
}
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);
mTextInfo.setText(info);
}
/**
* 释放VelocityTracker
*
* @see android.view.VelocityTracker#clear()
* @see android.view.VelocityTracker#recycle()
*/
private void releaseVelocityTracker() {
if(null != mVelocityTracker) {
mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
}
这样我们就可以求出move过程中的伪瞬时速度,这样在做很多控件的时候都是可以用到的,比如系统Launcher的分页,ScrollView滑动等,可根据此时的速度来计算ACTION_UP后的减速运动等。实现一些非常棒的效果。