Android事件传递机制
Android事件传递机制
- 事件传递机制–源码。
- 处理事件冲突。
Activity 事件分发
分别实现OnTouchListener 和 OnClickListener
- OnTouchListener
- OnClickListener
View的事件分发
View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。
- 先执行 dispatchTouchEvent()
- 再执行OnTouchEvent
1 | /** |
一般情况下,我们不该在普通View内重写dispatchTouchEvent方法,因为它并不执行分发逻辑。
当Touch事件到达View时,我们该做的就是是否在onTouchEvent事件中处理它。
View + ViewGroup的事件分发
ViewGroup的相关事件有三个:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent。
ViewGroup的onTouchEvent事件是什么时候处理的呢?
当ViewGroup所有的子View都返回false时,onTouchEvent事件便会执行。由于ViewGroup是继承于View的,它其实也是通过调用View的dispatchTouchEvent方法来执行onTouchEvent事件。
ViewGroup还有个onInterceptTouchEvent,看名字便知道这是个拦截事件。这个拦截事件需要分两种情况来说明:
1.假如我们在某个ViewGroup的onInterceptTouchEvent中,将Action为Down的Touch事件返回true,那便表示将该ViewGroup的所有下发操作拦截掉,这种情况下,mTarget会一直为null,因为mTarget是在Down事件中赋值的。由于mTarge为null,该ViewGroup的onTouchEvent事件被执行。这种情况下可以把这个ViewGroup直接当成View来对待。
2.假如我们在某个ViewGroup的onInterceptTouchEvent中,将Acion为Down的Touch事件都返回false,其他的都返回True,这种情况下,Down事件能正常分发,若子View都返回false,那mTarget还是为空,无影响。若某个子View返回了true,mTarget被赋值了,在Action_Move和Aciton_UP分发到该ViewGroup时,便会给mTarget分发一个Action_Delete的MotionEvent,同时清空mTarget的值,使得接下去的Action_Move(如果上一个操作不是UP)将由ViewGroup的onTouchEvent处理。
//ACTION_DOWN = 0, View消费Touch事件
//ViewGroup 先执行dispatchTouchEvent() 再执行onInterceptTouchEvent()
- dispatchTouchEvent:action–0—view:MyRelativeLayout
- onInterceptTouchEvent:action–0—view:MyRelativeLayout
//View 执行dispatchTouchEvent()
3. dispatchTouchEvent:action–0—view:MyButton
// View的onTouchListener 优先于 onTouchEvent()执行
4. OnTouchListener:acton–0—-view:com.ricky.event.MyButton
5. onTouchEvent:action–0—view:MyButton
//ACTION_UP = 1
6. dispatchTouchEvent:action–1—view:MyRelativeLayout
7. onInterceptTouchEvent:action–1—view:MyRelativeLayout
- dispatchTouchEvent:action–1—view:MyButton
- OnTouchListener:acton–1—-view:com.ricky.event.MyButton
- onTouchEvent:action–1—view:MyButton
//最后执行OnClickListener()
11. OnClickListener—-view:com.ricky.event.MyButton