View的事件体系
View 的事件体系
1.View的基础知识
-
View是所有控件的基类
-
View由四个顶点决定,top,left,right,bottom
-
x,y View左上角的坐标
-
translationX,translationY是View左上角相对于父容器的偏移量默认是0
-
x = left + translationX
-
y = top + translationY
-
MotionEvent 在手指接触屏幕后所产生的一系列事件中 典型的事件有如下几种:
- ACTION_DOWN---手指刚接触屏幕;
- ACTION_MOVE---手指在屏幕上移动;
- ACTION_UP---手机从屏幕上松开的一瞬间.
通过MotionEvent对象我们可以得到点击事件发生的x和y坐标
- getX/getY返回的是相对于当前View左上角的x和y坐标
- getRawX/getRawY 返回的是相对于屏幕左上角的x和y坐标
-
TouchSlop
- 系统能识别的被认为是滑动的最小距离.
- 获取这个常量:ViewConfiguration.get(getContext()).getScaledTouchSlop().
-
VelocityTracker
- 速度追踪,用于追踪手指在滑动过程中的速度,包括水平和竖直速度.
- VelocityTracker vt = VelocityTracker.obtain();
- vt.addMovement(event);
- vt.computeCurrentVelocity(1000);
- int xV= (int)vt.getXVelocity();
- int yV = (int)vt.getYVelcity();
- vt.clear();
- vt.recycle();
-
GestureDetector
- 手势检测,用于辅助检测用户的单击,滑动,长按,双击等行为.
2. View的滑动
View滑动的常见实现方式
- 通过View本身提供的scrollTo/scrollBy方法
- 通过动画给View施加平移效果来实现滑动
- 通过改变View的LayoutParams 是的View重新布局而实现滑动
3.View分发机制
实质上就是MotionEvent的事件分发机制。即当MotionEvent产生一个事件以后,系统需要把事件传递给一个具体的View的这样一个过程。他主要包括三个方法:dispatchTouchEvent onInterceptTouchEvent onTouchEvent.
- public boolean dispatchTouchEvent(MotionEvent e)
用来进行事件 经过该View的事件,一定会调用这个方法。返回结果受onIntercepterTouchEvent 和onTouchEvent影响。返回值表示是否消费事件。
- public boolean onInterceptTouchEvent(MotionEvent e)
在上述方法内部,判断是否拦截事件 同一个事件只会运行一次 返回结果表示是否拦截事件
- public boolean onTouchEvent(MotionEvent e)
在diapatchTouchEvent方法内部 用来处理点击事件 表示是否消耗该事件 同一事件序列只会执行一次
ViewGroup事件分发过程:
对于一个Viewgroup来说,接收到事件以后首先会调用diapatchTouchEvent 如果返回值是true 也就是说onInterceptTouchEvent返回true则表示自己消费这个事件 那么就会调用onTouchEvent方法;如果onIntercepterTouchEvent返回值是false,表示自己不处理该事件通过child.dispatchTouchEvent发送事件给子布局,如此反复 知道最后被处理。
View的事件优先级
当一个View设置了OnTouchListener以后 事件会先执行OnTouchListener的onTouch方法,如果onTouch返回为true 表示OntouchListener消费了事件 就不会传递到OntouchEvent;如果返回为false,才会传递到OntouchEvent,如果OntouchEvent返回为true,这OntouchEvent消费事件,后续额onClicklister就不会接收到事件,click方法就不会被调用;如果OntouchEvent返回为false 才会执行到click方法。 所以view的监听优先级 OnTouchListener > OnTouchEvent > OnClickListener
事件分发方法的执行顺序 dispatchTouchEvent->onIntercepteTouchEvent->OnTouchListener(onTouch)->onTouchEvent->onClickListener(click)