View的位置参数:
view的位置主要是由4个顶点确定的:top,left,right,bottom对应:
top = getTop();
left = getLeft();
right = getRight();
bottom =getBottom();
同时我们可以得到view的宽高与之对应的关系:
with = right -left;
height = bottom -top ;
Android 3.0之后添加了:x,y,translationX,translationY
x,y对应View左上角的坐标。translationX和translationY是View左上角相对于父容器的偏移量。
x = left + translationX ;
y = top +translationY ;
MotionEvent
- ACTION_DOWN
- ACTION_UP
- ACTION_MOVE
- ACTION_OUTSIDE
- ACTION_CANCEL:其他都比较好理解,这个比较难理解,一般是父View将事件拦截了,才会走这个
TouchSlop
指系统所能识别为滑动操作的最小距离,不同机型可能不同,可通过代码获取:
ViewConfiguration.get(this).getScaledTouchSlop();
Velocity Tracker (速度跟踪器)
这个一看就是来获取当前滑动速度的,因此我们一般应该在onTouchEvent方法中使用;
初始化方法:
VelocityTracker velocityTracker = VelocityTracker.obtain();
很显然创建了一个速度跟踪器了,肯定还得设置跟踪的事件:
velocityTracker.addMovement(event);
再来看看获取当前速度的API:
public void computeCurrentVelocity(int units) ;
public void computeCurrentVelocity(int units, float maxVelocity);
速度 = 距离 / 时间段 ,所以上面在获取当前速度时,需要我们设置这个时间段,单位是ms,置于第二参数就是设置能测量的最大速度(maxVelocity)
我们在获取当前滑动事件的速度其实就是计算在这个时间段内划过了多少像素数。
平面上的速度是包含x,y方向的:
float xVelocity = velocityTracker.getXVelocity();
float yVelocity = velocityTracker.getYVelocity();
用完还需要重置回收:
velocityTracker.clear();
velocityTracker.recycle();
GestureDetector(手势探测器)
检测单击,双击,长按,滑动等行为。
public GestureDetector(Context context, OnGestureListener listener) ;
从上面的方法可以看出,在创建一个GestureDetector的时候需要传个GestureListener的实例。看了下源码有好几个Listener可以传:
OnGestureListener:
public interface OnGestureListener {
boolean onDown(MotionEvent e);
void onShowPress(MotionEvent e);
boolean onSingleTapUp(MotionEvent e);
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
void onLongPress(MotionEvent e);
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
}
注意:void onShowPress(MotionEvent e);是指手指轻轻触摸屏幕,尚未松开或拖动,需要注意它和onDown()的区别
OnDoubleTapListener:
public interface OnDoubleTapListener {
boolean onSingleTapConfirmed(MotionEvent e);
boolean onDoubleTap(MotionEvent e);
boolean onDoubleTapEvent(MotionEvent e);
}
注意: boolean onSingleTapConfirmed(MotionEvent e);如果触发,那么它后面就不可能再紧跟另一个单击行为,即要保证此次只可能为单击。
OnContextClickListener:
public interface OnContextClickListener {
boolean onContextClick(MotionEvent e);
}
SimpleOnGestureListener:
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
OnContextClickListener {
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return false;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
public void onShowPress(MotionEvent e) {
}
public boolean onDown(MotionEvent e) {
return false;
}
public boolean onDoubleTap(MotionEvent e) {
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
public boolean onContextClick(MotionEvent e) {
return false;
}
}
可以看到 SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,所以它监听是最全的。
Scroller(弹性滑动对象)
不得不感叹下,ios的滑动自己就带弹性的,android的过程是瞬间完成的,要实现这个过度效果就得用到Scroller。通常他与VIew的computeScroll配合使用。