Android事件传递机制

  1. 事件传递机制–源码。
  2. 处理事件冲突。

Activity 事件分发

分别实现OnTouchListener 和 OnClickListener

  1. OnTouchListener
  2. OnClickListener

View的事件分发

View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。

  1. 先执行 dispatchTouchEvent()
  2. 再执行OnTouchEvent
1
2
3
4
5
6
7
8
9
/**
* View
* @param ev
* @return
*/
public boolean dispatchTouchEvent(MotionEvent ev){
....//其他处理,在此不管
return onTouchEvent(event);
}

一般情况下,我们不该在普通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()

  1. dispatchTouchEvent:action–0—view:MyRelativeLayout
  2. 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

  1. dispatchTouchEvent:action–1—view:MyButton
  2. OnTouchListener:acton–1—-view:com.ricky.event.MyButton
  3. onTouchEvent:action–1—view:MyButton

//最后执行OnClickListener()
11. OnClickListener—-view:com.ricky.event.MyButton