我们知道,当我们的手指在屏幕上滑动时,会触发一系列的事件,那么这些事件是怎么触发以及处理的呢?我们带着这个问题来进入今天的学习当中。
1.MotionEvent
MotionEvent对象是android系统为了方便我们检测用户对屏幕的操作而生成的对象,我们可以通过这个对象轻松的监测到用户的操作。如当用户手指接触屏幕时,就会触发ACTION_DOWN事件,当用户手指离开屏幕时就会触发ACTION_UP事件,当用户手指在屏幕上滑动时就会触发ACTION_MOVE事件。正是因为有了这些触发事件的节点,我们才可以对用户的操作做出各种各样的反馈。
2.TouchSlop
TouchSlop是系统所能识别出的被认为是滑动的最小距离。换而言之,即就是如果我们的滑动距离小于这个值,则系统认为我们没有在屏幕上滑动。这是一个常量,和设备有关,在不同设备上这个值是不同的。
获取这个值的方式:ViewConfiguration.get(getContext().getScaledTouchSlop());
3.VelocityTracker
速度追踪,用于追踪手指在滑动过程中的速度,包括水平方向和竖直方向。
那么我们在哪里来使用它呢?很简单,既然是要追踪我们的滑动速度,那么只能在view的onTouchEvent()方法中了。
@Override
public boolean onTouchEvent(MotionEvent event) {
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
float vX = velocityTracker.getXVelocity();
float vY = velocityTracker.getYVelocity();
velocityTracker.clear();
velocityTracker.recycle();
return true;
}
如代码所示,在这段代码中首先要调用computeCurrentVelocity()方法来获取速度,方法中的参数1000,即代表每秒的滑动速度。
其次,在我们使用完毕后,需要回收velocityTracker这个对象,以免引起内存泄漏。
还有一个需要特别注意的就是方向问题,我们规定,手指顺着android系统坐标滑动所产生的速度为正值,逆方向则为负值。用如下公式来表示。
速度 = (终点位置 - 起点位置)/ 时间段;
4.GestureDetector
手势检测,用于辅助检测用户的单击,滑动,长按,双击等行为;
我们知道,如果没有这个类,那么我们检测用户的行为是通过onTouchEvent()方法来实现的。那么对于用户的种种行为我们都需要去通过计算来得到用户的操作到底是单击,双击或者长按等等。那么android系统为了避免我们去计算这些操作,直接替我们写好了这个辅助类,让我们可以直接判断出用户当前的操作行为。所以在不看源码的基础上我们就可以猜测出来,这个辅助类必然是通过劫持我们的onTouchEvent()来实现的。那么具体我们应该怎么来使用呢?
首先我们需要创建一个GestureDetector对象并实现OnGestureListener()接口或者OnDoubleTapListener()接口。接着,就需要接管目标view的onTouchEvent()方法了。
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector = new GestureDetector(this);
mGestureDetector.setIsLongpressEnabled(false);
boolean consume = mGestureDetector.onTouchEvent(event);
return consume;
}
@Override
public boolean onDown(MotionEvent motionEvent) {
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return false;
}
5.Scroller
弹性滑动对象,辅助操控view的滑动。我们知道,当使用view 的scrollTo/scrollBy方法来滑动view时,是瞬间移动过去的,没有过渡效果。那么为了美观可见,于是android官方系统为我们生成了一个这样的辅助类,那么我们该如何使用呢?
Scroller无法单独使view滑动,它需要和view的computeScroll()配合使用。Scroller的使用方法是固定的,如下代码:
private void smoothScrollTo(int destX , int destY){
int scrollX = getScrollX();
int delta = destX - scrollX;
mScroller.startScroll(scrollX,0,delta,0,1000);
invalidate();
}
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}