java 事件分发机制_用两段代码带你看懂事件分发机制

先来看一段精简版的源码

View.java

public class View {

private View.OnClickListener mOnClickListener;

private OnLongClickListener mOnLongClickListener;

private OnTouchListener mOnTouchListener;

public boolean dispatchTouchEvent(MotionEvent event) {

boolean result = false;

if (isEnabled()) {

if (mOnTouchListener != null &&

mOnTouchListener.onTouch(this, event)) {

result = true;

}

if (!result && onTouchEvent(event)) {

result = true;

}

}

return result;

}

public boolean onTouchEvent(MotionEvent event) {

final int action = event.getAction();

if (isClickable()) {

switch (action) {

case MotionEvent.ACTION_UP:

performClick();

break;

case MotionEvent.ACTION_DOWN:

performLongClick();

break;

default:

break;

}

return true;

}

return false;

}

public boolean performClick() {

final boolean result;

if (mOnClickListener != null) {

mOnClickListener.onClick(this);

result = true;

} else {

result = false;

}

return result;

}

public boolean performLongClick() {

boolean handled = false;

if (mOnLongClickListener != null) {

handled = mOnLongClickListener.onLongClick(this);

}

return handled;

}

public void setOnClickListener(OnClickListener listener) {

mOnClickListener = listener;

}

public void setOnLongClickListener(OnLongClickListener listener) {

mOnLongClickListener = listener;

}

public void setOnTouchListener(OnTouchListener listener) {

mOnTouchListener = listener;

}

}

ViewGroup.java

public class ViewGroup extends View {

private boolean mDisallowIntercept;

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

boolean handled;

final int action = event.getAction();

boolean intercepted = false;

switch (action) {

case MotionEvent.ACTION_DOWN:

if (!mDisallowIntercept) {

intercepted = onInterceptTouchEvent(event);

}

break;

default:

break;

}

if (!intercepted) {

View childView = findFocus();

handled = childView.dispatchTouchEvent(event);

} else {

handled = super.dispatchTouchEvent(event);

}

return handled;

}

public boolean onInterceptTouchEvent(MotionEvent event) {

return false;

}

public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {

mDisallowIntercept = disallowIntercept;

}

}

思维导图

e243838fb3ae

主要方法解释

dispatchTouchEvent:事件分发方法

返回 false:分发事件

返回 true:不分发事件

默认返回值:false

onInterceptTouchEvent:事件拦截方法

返回 false:不拦截事件

返回 true:拦截事件

默认返回值:false

onTouchEvent:事件消费方法

返回 false:不消费事件

返回 true:消费事件

默认返回值:false

其他方法解释

setOnClickListener:设置点击事件,会在 performClick 方法中回调监听,而 performClick 方法在 onTouchEvent 方法收到 UP 事件中回调

setOnLongClickListener:设置长按事件,会在 performLongClick 方法中回调监听,而 performLongClick 方法在 onTouchEvent 方法收到 DOWN 事件中回调

setOnTouchListener:设置触摸事件,会在 dispatchTouchEvent 方法中回调监听,如果 OnTouchListener.onTouch 返回 true,则不会执行 View 内部的 onTouchEvent 方法,表示触摸事件已经被外部监听消化了,如果需要在这个方法派发点击事件或者长按事件,可以直接调用 performClick 或者 performLongClick

requestDisallowInterceptTouchEvent:设置 ViewGroup 在 dispatchTouchEvent 方法是否要执行 onInterceptTouchEvent 方法,如果不执行则会直接下发事件给到子 View 的 dispatchTouchEvent 方法中

事件类型解释

MotionEvent.ACTION_DOWN:手指按下事件,第一个接收到的事件,整个触摸过程只有一次

MotionEvent.ACTION_MOVE:手指移动事件,整个触摸过程有 N 次,需要注意不能拿这个事件来判断当前是否单击了 View,因为就算单击也有可能产生 MOVE 事件,这个是经验之谈

MotionEvent.ACTION_UP:手指抬起事件,和 DOWN 事件对应,整个触摸过程也只有一次

MotionEvent.ACTION_CANCEL:取消事件,非人为原因结束本次事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值