viewgroup
// ViewGroup中该方法的核心部分伪代码
// ViewGroup中该方法的核心部分伪代码
public boolean dispatchTouchEvent(MotionEvent ev) {if (!onInterceptTouchEvent(ev)) {return child.dispatchTouchEvent(ev); //不拦截,则传给子View进行分发处理} else {return onTouchEvent(ev); //拦截事件,交由自身对象的onTouchEvent方法处理}
ViewGroup的该方法与Activity的类似,只是新添了一个onInterceptTouchEvent方法。当事件传入时,首先会调用onInterceptTouchEvent。
- 如果该方法返回了FALSE(表示不拦截),则交给子View去调用dispatchTouchEvent()方法
- 如果该方法返回了TRUE(表示拦截),则直接交给该ViewGroup对象的onTouchEvent(ev)方法处理,具体是否能处理以onTouchEvent()的实际情况为准。
View的dispatchTouchEvent方法
// View中该方法的核心部分伪代码
public boolean dispatchTouchEvent(MotionEvent ev) {//如果该对象的监听成员变量不为空,则会调用其onTouch方法,if (mOnTouchListener != null && mOnTouchListener.onTouch(this, event)) {return true; //若onTouch方法返回TRUE,则表示消费了该事件,则dispachtouTouchEvent返回TRUE,让其调用者知道该事件已被消费。}return onTouchEvent(ev); //若监听成员为空或onTouch没有消费该事件,则调用对象自身的onTouchEvent方法处理。
}
从该方法的核心逻辑中可以看到,事件传递进来后,首先会对mOnTouchListener判空,如果之前Set了Listener,则会调用其onTouch方法。
- 若onTouch方法返回TRUE,则dispatchTouchEvent也会返回TRUE,表示消费该事件。
- 若onTouch方法返回FALSE,或者mOnTouchListener本来就是空,则调用自身的onTouchEvent()来处理,是否消费事件,可以由其返回值判断。
实际上,在View的onTouchEvent方法中,如果设置了onClickListener监听对象,则会调用其onClick方法。
在同时设置了onTouchListener与onClickListener对象的情况下,正是由于View的dispacthTouchEvent方法会先调用mOnTouchListener的onTouch,才会调用onTouchEvent方法,所以onTouchListener对象的onTouch方法是优先于onClickListener对象的onClick方法调用的。