1.事件分发核心方法
- dispatchTouchEvent (事件分发,activity,ViewGroup,View 拥有)
- 返回true表示事件分发成功,事件消费
- 返回false表示分发事件失败,事件传递到上层View的onTouchEvent
- 默认调用super.dispatchTouchEvent ,分发事件,执行分发流程,
- onInterceptTouchEvent(事件拦截,ViewGroup拥有)
- 返回true,表示进行拦截,不会进行事件分发到子View,有viewgroup调用自己的onTouchEvent方法进行处理。
- 返回false,不进行拦截,执行既定的分发过程
- ViewGroup默认不拦截事件
- onTouchEvent(事件消耗,activity,ViewGroup,View 拥有)
- 执行到该方法说明该View/ViewGroup在触摸返回内
- 返回true,表示触摸事件被该view消费掉
- 返回false,表示触摸事件该View没有消费掉,则依次回溯到上层传递的
2. 事件分发流程
- 分发流程:Activity======>ViewGroup(触摸区域内)====>View(触摸区域内)
- 消费流程:View(onTouchEvent 返回false)======>ViewGroup(onTouchEvent 返回false)=====>Activity
2.1分发流程结论
- ACTION_DOWN 事件会一直分发到最底层的View并交由它的onTouchEvent方法处理,返回false,表示它不处理该事件序列,后续的move,up,等事件将不会向他分发。同理与这个事件序列的所有View,当所有View都没有消费这个事件则最后调用activity的onTouchEvent方法,后续的move,up事件直接由activity的 dispatchTouchEvent (activity) ======>onTouchEvent(activ)
- 事件拦截onInterceptTouchEvent,可以拦截所有事件,也可以拦截部分事件,down-move-up,子View可以调用父View的requestDisallowInterceptTouchEvent,不允许父View拦截,但如果父View拦截了Down事件,这个方法是无效的。
- view什么时候会消耗事件,即onTouchEvent返回true,clickAble或longclickable有一个为真,具体表示就是添加相关的监听事件,表示我们有相关业务需要处理。mOnTouchListener的ontouch事件要优先于onTouchEvent事件,当返回true时,表示事件已经被消费,不会再进行分发。
view的dispatchTouchEvent 部分源码
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
setOnTouchListener
/**
* Register a callback to be invoked when a touch event is sent to this view.
* @param l the touch listener to attach to this view
*/
public void setOnTouchListener(OnTouchListener l) {
getListenerInfo().mOnTouchListener = l;
}
setOnClickListener
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* clickable, it becomes clickable.
*
* @param l The callback that will run
*
* @see #setClickable(boolean)
*/
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
setOnLongClickListener
/**
* Register a callback to be invoked when this view is clicked and held. If this view is not
* long clickable, it becomes long clickable.
*
* @param l The callback that will run
*
* @see #setLongClickable(boolean)
*/
public void setOnLongClickListener(@Nullable OnLongClickListener l) {
if (!isLongClickable()) {
setLongClickable(true);
}
getListenerInfo().mOnLongClickListener = l;
}
3.事件序列
一个事件序列包含ACTION_DOWN(1次) -> ACTION_MOVE(N次) -> ACTION_UP(1次),事件分发包含一个完整的事件序列(从屏幕的的触摸到离开的过程)。

网友评论