1.VelocityTracker
速度追踪,用于获取手指滑动的速度,包括水平移动和纵向移动,使用方法如下:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//追踪手指滑动的速度
VelocityTracker obtain = VelocityTracker.obtain();
obtain.addMovement(event);
//获取之前先调用 设置速度
obtain.computeCurrentVelocity(1000);
//滑动时 获取当前的速度
float xVelocity = obtain.getXVelocity();
float yVelocity = obtain.getYVelocity();
Log.i(TAG,"xVelocity:"+xVelocity);
Log.i(TAG,"yVelocity:"+yVelocity);
打印结果如下:
01-05 09:16:58.762 4435-4435/com.example.zyl.levelprogressbar I/ContentValues: xVelocity:2742.4805
01-05 09:16:58.762 4435-4435/com.example.zyl.levelprogressbar I/ContentValues: yVelocity:122.3594
01-05 09:16:58.780 4435-4435/com.example.zyl.levelprogressbar I/ContentValues: scaledDoubleTapSlop: 263
01-05 09:16:58.780 4435-4435/com.example.zyl.levelprogressbar I/ContentValues: xVelocity:4127.6157
01-05 09:16:58.780 4435-4435/com.example.zyl.levelprogressbar I/ContentValues: yVelocity:-0.0051030186
obtain.computeCurrentVelocity(1000);
最后不需要的时候需要重置并回收内存
obtain.clear(); obtain.recycle();
2.GestureDecector
用于监听用户的手势滑动情况,单击、滑动、长按行为。首先new对象,并实现里面的接口
gestureDetector = new GestureDetector(this);
//解决长安屏幕无法拖动的问题
gestureDetector.setIsLongpressEnabled(true);
@Override
public boolean onDown(MotionEvent e) {
//手指触摸屏幕的一瞬间
return false;
}
@Override
public void onShowPress(MotionEvent e) {
//触摸屏幕 尚未松开和移动
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
//单击
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//移动
return false;
}
@Override
public void onLongPress(MotionEvent e) {
//长按屏幕不放
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//快速滑动行为
return false;
}
@Override
public boolean onDown(MotionEvent e) {
//手指触摸屏幕的一瞬间
return false;
}
@Override
public void onShowPress(MotionEvent e) {
//触摸屏幕 尚未松开和移动
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
//单击
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//移动
return false;
}
@Override
public void onLongPress(MotionEvent e) {
//长按屏幕不放
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//快速滑动行为
return false;
}
3.Scroller
用来实现view的滑动效果,Scroller本身没有滑动效果,需要配合computeScroll方法使用,可以展现出效果,固定代码;
@Override
public void computeScroll() {
if (scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(),scroller.getCurrY());
postInvalidate();
scroller.abortAnimation();
}
}
computeScroll()方法是空实现,因此需要我们自己去实现,而正是因为这个方法,View才能实现惯性滑动;
原理:当view冲会后会调用computeScroll()方法,而computeScroll又会向Scroller调用scrollX和scrollY,然后通过scrollTo方法实现移动;然后在调用postInvalidata()进行第二次重绘;反复如此,调用computeScroll方法,继续获取当前的scrollX和scrollY,知道滑动结束;
computeScrollOffset()这个方法会根据时间的流逝来计算scrollX和scrollY的值,返回true继续滑动,返回false滑动结束;
public boolean computeScrollOffset() {
if (mFinished) {
return false;
}
int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
if (timePassed < mDuration) {
switch (mMode) {
case SCROLL_MODE:
final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
mCurrX = mStartX + Math.round(x * mDeltaX);
mCurrY = mStartY + Math.round(x * mDeltaY);
break;
...
return true
总结(Scroller的工作机制)
Scroller本身不具有滑动效果,需要配合View的computeScroll()方法进行不断的重绘,从而实现滑动效果,而且每次滑动重绘到互动的开始都会有一个间隔,在这个时间内Scroller就会得到View的位置,然后通过ScrollTo移动,反复重复就会实现弹性滑动的效果;