如果接触android开发时间足够长的话,或多或少都会遇到各种各样事件冲突的问题,要想解决这类问题,对深入理解事件分发机制是很有必要的,接下来几天都会尽自己所能尽可能将这方面讲清楚。
View的事件分发主要还是对触摸操作,按下,滑动,抬起过程中的事件处理;而所有的触摸事件都被封装在MotionEvent里面;那么MotionEvent包括哪些事件类型呢?
- Action_Down -- 手指按下的时候;
- Action_Move--手指在屏幕上移动的时候;
- Action_Up--手指抬起的时候;
- ACTION_CANCEL--动作取消;
- ACTION_OUTSIDE--动作超出边界的情况;
- ACTION_POINTER_DOWN 多点按下
- ACTION_POINTER_UP 多点弹起
一次完整的事件都要经历从按下到抬起的整个过程,也就是说要经历Action_Down-->Action_Up的整个流程。
事件的分发处理主要依靠如下三个方法来进行处理:
- dispatchTouchEvent():用来进行事件分发,返回true,当前view消费事件,并停止下发,否则事件交给父view的onTouchEvent来进行处理。
- onInterceptTouchEvent()用来拦截事件,返回true,交给自己的onTouchEvent来进行处理,false,交给子View的onInterceptTouchEvent来处理。
- ontouchEvent()用来处理点击事件,返回true,处理事件,返回false,拦截事件并处理。
ViewGroup和View的区别:
View没有拦截事件onInterceptTouchEvent事件,而ViewGroup上面事件都有。
ViewGroup:
当点击的时候,dispatchTouchEvent会被调用,onInterceptionTouch方法为true,就拦截事件,并将事件交给ontouchEvent来处理;onInterceptionTouch方法为false,不拦截事件,事件继续向下传递,子view可能是viewgroup也有可能是view。如果是viewGroup,则处理对应前面的内容,不断循环,直到view。
View:
- 设置ontouchListener:回调ontouch事件,如果ontouch返回false,ontouchEvent会被调用,否则,不会调用。处理的优先级outouchListener>ontouchEvent>onclicklistener。
- 事件传递顺序:activity -->window -->view,view的onTouchEvent返回false,父容器onTouchEvent将会调用,如果都不处理,最后传递给activity处理。
- viewGroup默认不拦截任何事件。onIntercepTouchEvent默认返回false。
- View默认没有onIntercepTouchEvent事件,事件传递到View,onTouchEvent会被调用。
- 事件总是先传递给父组件,再传给子组件,子组件通过requestDisallowInterceptTouchEvent干预父组件的事件分发。