您的位置:首页 > 移动开发 > Android开发

Android View、ViewGroup 事件分发机制(一)

2014-09-11 17:13 597 查看
View事件分发涉及的方法:onTouch、dispatchTouchEvent、onTouchEvent 。

ViewGroup事件分发涉及的方法:onTouch、dispatchTouchEvent、onTouchEvent 、onInterceptTouchEvent。

1. Button点击事件响应流程

点击Button --> 调用Button的dispatchTouchEvent -->调用TextView的dispatchTouchEvent方法

--> 调用View的dispatchTouchEvent方法,我们来看下View的dispatchTouchEvent方法内部

public boolean dispatchTouchEvent(MotionEvent event) {
        if (!onFilterTouchEventForSecurity(event)) {
            return false;
        }
// 1. 设置过监听,2.按钮是ENABLED(默认为true) 3.onTouch方法返回true
        if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && mOnTouchListener.onTouch(this, event)) {
            return true;
        }
        return onTouchEvent(event);
    }

第一种情况:当1和2为真的时候,才会执行3,当3中onTouch方法返回true的时候,dispatchTouchEvent返回true,

也就标志着此事件被消耗。

第二种情况:当1和2为真的时候,才会执行3,当3中onTouch方法返回false的时候,调用onTouchEvent方法,

下面我们看看这个方法内部。

public boolean onTouchEvent(MotionEvent event) {
final int viewFlags = mViewFlags;
if ((viewFlags & ENABLED_MASK) == DISABLED) {
return (((viewFlags & CLICKABLE) == CLICKABLE ||(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
}
if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
// 判断View是否是可点击的,如果可点击则UP之后会执行到performClick方法,此方法中会调用onClick方法处理相应逻辑,并返回true
// 如果不是可点击的,则始终会返回false
if (((viewFlags & CLICKABLE) == CLICKABLE ||(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
boolean prepressed = (mPrivateFlags & PREPRESSED) != 0;
if ((mPrivateFlags & PRESSED) != 0 || prepressed) {
boolean focusTaken = false;
if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
focusTaken = requestFocus();
}
if (!mHasPerformedLongPress) {
removeLongPressCallback();
if (!focusTaken) {
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
}
}
}
break;
case MotionEvent.ACTION_DOWN:
...
break;
...
case MotionEvent.ACTION_CANCEL:
break;
...
case MotionEvent.ACTION_MOVE:
break;
}
return true;
}
return false;
}
下面我们简单的看一下performClick这个方法吧

public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
if (mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
//执行点击事件业务逻辑,并返回true消费此事件
mOnClickListener.onClick(this);
return true;
}
return false;
}


2. ImageView点击事件响应流程

ImageView和Button的区别是:ImageView默认是不可点击的,也就是说如果执行到onTouchEvent方法,此方法会一直返回false,也就是dispatchTouchEvent方法返回false,此事件就不会被消耗就只会执行一次ActionDown操作.

当然,如果想对ImageView添加点击事件,可以设置它的clickable属性。

注意:官方文档对dispatchTouchEvent的返回值的解释是:True if the event was handled by the view, false otherwise。

我们可以简单的理解为如果返回true,就说明它需要处理这个事件,就让它接收所有的触屏事件,否则,说明它不用处理,也就不让它接收后续的触屏事件了。

如果你感兴趣,请继续阅读《Android View、ViewGroup 事件分发机制(二)》

Demo下载请猛戳
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: