事件传递的过程分析
- 事件传递 从最外层父View将事件 传递到 内部View 首先传递前 判断自己的dispatchTouchEvent 方法是否支持分发,支持分发的话,会传递自己View的onInterceptTouchEvent 方法,看自己是否进行拦截处理,若拦截则会传递到自己的onTouchEvent,若不拦截会传递到子View的dispatchTouchEvent 方法进行处理,内部处理流程和上一层View的处理流程一样: dispatchTouchEvent–>onInterceptTouchEvent–>onTouchEvent
DispatchTouchEvent之return
false: 返回给父View的OnTouchEvent事件
true :停止传递分发、事件不传递、也就是不会有onTouchEvnet事件之说,因为onTouchEvent事件,执行的时候是事件全部传到最底部View后才会执行,最底部的onTouchEvent不消费的话,才会向上一级的父View的onTouchEvent传递(也就是才会执行到父View的该方法、、当然除非是中间拦截了,才会不向下传递、直接执行自己的OnTouchEvent方法)
super.DispatchTouchEvent之return:支持分发(也就是该事件已经产生、会进行处理、直到有人将其消费、如果返回上边的,该事件就相当于没有产生,直接返给窗体View、直接被扼杀在摇篮里)、会传递到该View的onInterceptTouchEvent方法,由该方法来处理看是否继续向下传递;
onInterceptTouchEvent之return
- false: 不拦截传递给下一层子View进行事件分发方法:dispatchTouchEvent() 流程相同继续走。
- true: 拦截事件,不向下传递事件,会传递给自己的onTouchEvent()事件处理响应。
- super.onInterceptTouchEvent(): 等同于true,即进行拦截,交由自己的onTouchEvnent进行处理
onTouchEvent()之return
- false: 不消费、传递到上一层的View的onTouchEvnet?
- true : 消费,自己执行onTouchEvnet方法
super.onTouchEvnet(): 等同于false 传递到上一层父View的 onTouchEvent进行处理
event.getPointerCount()//判断手指 MotionEvent.ACTION_XXX MotionEvent.ACTION_UP//需要全部手指全部离开屏幕才会调用 MotionEvent.ACTION_POINTER_UP//当存在多个手指触碰时,抬起一指就会执行该方法 MotionEvent.ACTION_POINTER_DOWN
GestureDetector 手势管理之OnGestureListener
void onShowPress(MotionEvent e);
boolean onSingleTapUp(MotionEvent e);
void onLongPress(MotionEvent e);
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
接收方式
- onTouchEvent 内部调用—mGestureDetector.onTouchEvent(event);
子View控制父View拦截
getParent().requestDisallowInterceptTouchEvent(true);
true:表示父View对事件进行拦截无效例如:onInterceptTouchEvent内部对事件down、move返回true,也是不起作用的
false:表示父View对内部子View的拦截是有效的
总结
所有的事件都是先往最底层传递的、最底层没有消费时才会一层一层的往外层传到各自的onTouchEvent()方法中,但是事件首先都是会执行DispatchTouchEvent方法进行分发传递到下一层的,其中会走每一层的:DispatchTouchEvent和onInterceptTouchEvent方法判断是不是需要拦截,不拦截就继续往下一层走,所以onInterceptTouchEvent的Down事件是都会走的,:包括MOVE事件、UP事件,当最外层的事件把Down拦截了,下边的就不会走了,当没有拦截,会一层一层走,,当最底层有方法表示
`getParent().requestDisallowInterceptTouchEvent(true);`
谁都不能拦截我的事件,那么事件就不会往上在传递到外层的move、up等事件了就会到该处消费结束!!!也就是说这个时候onInterceptTouchEvent的MOVE事件和UP事件都不会走了(对应的方法都不走了),其他情况还是每一层新的事件都会进行传递所以会出现那种:不拦截Down事件拦截Move事件的情况,,所以如果底部有拦截但是外层也想获取点击的坐标位置:就可以在onInterceptTouchEvent方法的down事件中进行获取点击的坐标位置、