本章主要介绍:
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)