什么是View
我们都知道,TextView是View,Button也是View,但View不仅仅是一个视图,显示给用户看,还可以与用户交互。LinearLayout是一个ViewGroup,而ViewGroup是View的一个子类,所以也是一个View。ViewGroup和它所包含的一个View组成一个View树结构,这对接下来说到View事件的传递很重要。先有个概念。
View位置参数
要确定给一个View的位置,要知道这个View的left,top,right,bottom,View额外还有x,y,translationX,translationY。
我相信这个图已经很好的解析了left,top,right,bottom的意思了,还指出了Android手机的起始标志(0,0)是手机屏幕的左上角。(其实java swing也是一样的)
x,y是View左上角的坐标。而translationX和translationY指的是View的偏移量。其实是这么一回事
x = translationX + left; y = translationY + top;MotionEvent和TouchSlop
MotionEvent这个我们很熟悉了,我们监听onTouch事件时,作为参数给我们使用。MotionEvent常用的一些事件类型,如ACTION_DOWN,ACTION_MOVE,ACTION_UP,其实已经很熟悉了。
MotionEvent的getX()/getY()和getRawX()/getRawY()这个两对方法都是用于获取我们Touch屏幕的坐标,可以这两个坐标是不一样的。
getX()/getY() 获取的是相对于View左上角的x,y坐标。 getRawX()/getRawY() 获取的是相对于手机屏幕左上角的x,y坐标TouchSlop是我第一次知道一个变量,Android系统用这个变量来判断最小的滑动距离。如果两次滑动之间的距离小于这个变量值,系统会判断不认为你在滑动。这样做为了更好的用户体验。这个值和设备有关,不是一个固定的值。我们可以调用ViewConfiguration.get(getContext()).getScaledTouchSlop()获取这个变量值。我们可以根据这个变量仿Android处理一些滑动。
VelocityTracker
这个类可以追踪手指的速度,一般用在onTouch()方法中使用。
VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event);获取当前滑动速度
// 1000是毫秒数,设置单位时间,计算速度,这方法必须先调用 velocityTracker.computeCurrentVelocity(1000); // 获取x和y方向的滑动速度,其实获取的是单位时间内启动的像素点,所以前面一定要先设置单位时间计算速度 int xVelocity = (int) velocityTracker.getXVelocity(); int yVelocity = (int) velocityTracker.getYVelocity();GestureDetector
手势监听,检测用户单击,滑动,长按,双击等行为。也可以在onTouch()中使用。
// myOnGestureListener是OnGestureListener的一个实现类 GestureDetector gestureDetector = new GestureDetector(this, myOnGestureListener); // 解决长按无法拖动问题 gestureDetector.setIsLoogpressEnable();然后在onTouch()方法内接管View的onTouch事件
boolean consum = gestureDetector.onTouchEvent(event); return consum;书中详细列了很多方法,有兴趣可以看书。常用的有一下几种:
onSingleTapUp(单击)onFling(快速滑动)onScroll(拖动,我还以为是滑动呢)onLongPress(长按)onDoubleTap(双击)Scroller
弹性滑动对象,用于View的弹性滑动。利用View的scrollTo和scrollBy是瞬间滑动,用户体验不好。Scroller就可以实现View的弹性滑动,不过要配合View的computeScroll方法一起用。下面是一段经典的贪心滑动代码。
Scroller scroller = =new Scroller(this); private void smoothScrollTo(int destX, int destY) { // 只滑动X int scrollX = getScrollX(); int scrollY = getScrollY(); int delta = destX - scrollX; scroller.startScroll(scrollX, scrollY, delta, 0, 1000); invalidate(); } @Override public void computeScroll() { // 返回ture表示动画没有完成 if (scroll.computeScrollOffset()) { scrollTo(scroll.getCurrentX(), scroll.getCurrentY()); postInvalidate(); } }我们先知道Scroller怎么使用,接下来会知道其原理。