本章主要介绍:

view基础,MotionEvent,TouchSlop,VelocityTracker,GestureDetetor,Scroller,view滑动,弹性滑动,事件分发机制

1.view的基础概念

view:android中所有控件的基类。

viewGroup:控件组。

2.view的位置几种表示法:

①.view.getLeft(),view.getRight(),view.getTop(),view.getBottom()        相对父布局的位置参数

②.view.getX(),view.getY()                                                                 相对父布局左上角的坐标,getX() = getLeft()+getTranslationX()

③.view.getTranslationX(),view.getTranslationY()                                相对于原始位置的偏移量,例如:属性动画让其偏移后产生的偏移坐标

④.event.getX(),event.getY()                                                                触摸事件相对父布局左上角的坐标(view中motionEvent参数的位置)

⑤.event.getRawX,event.getRawY()                                                    触摸事件相对屏幕左上角的坐标(view中motionEvent参数的位置)

参考:Android View坐标系详解(getTop()、getX、getTranslationX...)_张可_的博客-博客

3.MotionEvent和TouchSlop

MotionEvent常用的事件类型:

ACTION_DOWN:手指刚触摸屏幕

ACTION_MOVE:手指在屏幕上移动

ACTION_UP:手指离开屏幕的一瞬间

ACTION_CANCEL:被取消的事件(比如:action_down分发给了子控件,action_move和action_up没有分发给子控件,此时子控件的ACTION_CANCEL会被调用)

ACTION_POINTER_DOWN:有非主要手指按下时

ACTION_POINTER_UP:有非主要手指抬起时

TouchSlop:最小滑动距离(为了提升用户体验如果滑动距离小于这个值可以默认没滑动)

4.VelocityTracker、GestureDetector、OnDoubleTapListener和Scroller

VelocityTracker:速度追踪。

GestureDetector.OnGestureListener:监听单击滑动长按等动作。方法如下:

onDown:用户按下屏幕

onShowPress:按下时间超过瞬间,而且按下的时候没有松开或者拖动

onLongPress:长按触摸屏,超过一定时长

onSingleTapUp:单击后立即抬起,除了onDown不能用任何其他操作

onFling:滑屏,用户按下触摸屏,滑动后松开,只有最后一次触发(如果慢慢拖动不会触发)

onScroll:在屏幕中拖动事件,可能有连续多次触发,然后以onFling结尾

GestureDetector.OnDoubleTapListener:监听双击动作。

onSingleTapConfirmed:确认是单击事件,与onDoubleTap互斥

onDoubleTap:双击事件

onDoubleTapEvent:获取双击之间发生的动作(第一次点击和第二次点击之间,在onDoubleTap之后调用)

Scroller:弹性滑动对象,用于实现弹性滑动的。

5.view的滑动

①.ScrollTo、ScrollBy:

     (1)都是对view的内容进行滑动;

     (2)ScrollBy本质调用了ScrollTo;

     (3)注意滑动时向左(向上)为正值,向右(向下)为负值

②.动画:

       (1)view动画(并没有真正改变位置)

       (2)属性动画(真正改变位置)

③.布局位置(layout,offsetLeftAndRight,offsetTopAndBottom)

④.布局参数(LayoutParams)

6.view的弹性滑动

①Scroller+computeScroll+scrollTo

Ⅰ.新建Scroller实例;

Ⅱ.调用scroller.startScroll()方法并将滑动耗时和起始点位置传入,并且调用invalidate()方法进行重绘,重绘调用到draw()方法,draw()方法中调用到computeScroll()方法;

Ⅲ.重绘过程中调用到computeScroll()方法,在方法中调用scroller.computeScrollOffset()方法判断是否滑动结束,并且在调用computeScrollOffset()方法中会对scroller中的x、y进行处理得到新的滑动位置,没有结束则调用scrollTo方法并通过scroller获取滑动的位置,然后调用invalidate()方法继续重绘,轮询调用到computeScroll()方法。

②动画

③延时策略(Handler,view.postDelayed)

7.事件分发机制(重点):事件分发过程dispatchTouchEvent,onIntercepteTouchEvent,onTouchEvent;

①一个事件序列一旦被某个view拦截,那么后续的事件都交给他处理。

②如果view的某个事件不消耗ACTION_DOWN,那么同一个事件的其他事件都不会交给他处理,会交给他的父布局处理。

③如果view的某个事件不消耗除ACTION_DOWN之外的事件,那么这个事件会消失,最后消失的点击事件会交给Activity处理。

viewGroup默认不拦截事件。

view没有onInterceptTouchEvent方法,一旦点击事件传给他,就会调用他的onTouchEvent方法。

view的ontouchevent默认消耗事件。

onclick发生的前提是当前事件是可点击的。

⑧子view可以通过requestDisallowInterceptTouchEvent方法干预父元素的事件分发过程,但ACTION_DOWN除外。

⑨源码分析可得事件优先级onTouch---->onTouchEvent---->onClick。

⑩view的enabled是false不会影响onTouchEvent的返回值,但是会让此控件不可点击。

8.事件滑动冲突

①外部拦截法(通过父布局的OnIntercepteTouchEvent方法)

②内部拦截法(通过子view的OnTouchEvent方法和requestDisallowInterceptTouchEvent及父布局的OnIntercepteTouchEvent)