当前位置: 代码迷 >> 综合 >> 事件分发
  详细解决方案

事件分发

热度:83   发布时间:2024-02-05 21:57:34.0

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方法调用的。

  相关解决方案