Aandroid 事件分发机制解析
注册点击事件跟触摸事件,触摸笔点击先触发。从代码上说就是:
点击按钮 会调用 dispatchTouchEvent 方法,按钮的button 里没有 父类textview 也没有,在网上 view 父类 存在。
dispatchTouchEvent 方法 有三个条件判断 如果三个条件都为TRUE 方法就返回true 否则就执行onTouchEvent(event) 方法。
三个条件: 第一个条件 mOnTouchListener 只要给控件注册touch时间 mOnTouchListener就被赋值;
第二个条件(mViewFlags & ENABLED_MASK) == ENABLED 判断是否可以enable 按钮都默认enable 所以这个恒true;
第三个条件 mOnTouchListener.onTouch(this, event),其实就是注册touch时间onTouuch方法 ,
只要这里onTouch 返回true,三个条件都成立。否则就执行onTouchEvent(event)方法;
到这就可以看出 onTouch 优先于 onClick, 如果 onTouch 返回true dispatchTouchEvent 方法直接返回true 就不会执行下去;
也就是说 onTouch 返回true onClick 就不执行了。可以说 onClick方法存在于onTouchEvent中。
case MotionEvent.ACTION_UP:
...
if (!mHasPerformedLongPress) {
...
if (!post(mPerformClick)) {
performClick();
}
...
源码中MotionEvent.ACTION_UP 里调用 perfromClick() 方法;
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
if (mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnClickListener.onClick(this);
return true;
}
return false;
}
到这之后又哪给 mOnClickListener 赋值 之后又找到这个方法
public void setOnClickListener(OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
mOnClickListener = l;
}
这样就清晰了, 点击事件 找到 dispatchTouchEvent 三个条件 有不满足的就进 onTouchEvent 中 当点击是 就会给 mOnClickListener赋值,
进入perfromClick()方法中 回调 onClick方法。
还有个注意的;
dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发后一个action
在源代码中 你会发现 不管当前的action 是什么都会执行 return true;
浙公网安备 33010602011771号