之前一直没有时间写东西,现在打算写一篇关于事件分发机制的文章.关于这类文章网上肯定有许多而且还比我 的好的,我只是尽我最大努力讲清楚,也让我重新梳理一下.
onTouch , onClick, onTouchEvent的关联和区别
- onTouch方法
myButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i(TAG, "onTouch" + event.getAction());
return false;
}
});
我们通常用法就是这样,通过event.getAction()方法来判断用户ACTION_DOWN, ACTION_UP, ACTION_MOVE操作.那和onTouchEvent()有什么区别呢?我们看下onTouchEvent()方法
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG, "onTouchEvent" + event.getAction());
return true;
}
发现它也可以有event 也可以判断用户操作 ,那我们应该怎么用,用哪个呢? 在这我要再讲一个方法
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.i(TAG, "dispatchTouchEvent" + event.getAction());
return super.dispatchTouchEvent(event);
}
这个方法有什么用呢? 是这样的,这个方法当我们对控件view进行触摸的时候都会首先调用这个方法,它起到一个分发触摸事件的作用.是这样吗?我们看下我打印的log就知道了
09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent0
09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouch0
09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouchEvent0
09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent2
09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouch2
09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouchEvent2
09-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent2
09-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: onTouch2
09-01 13:22:40.352 2985-2985/com.xu.startservice I/==========>: onTouchEvent2
09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent1
09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouch1
09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouchEvent1
09-01 13:22:40.358 2985-2985/com.xu.startservice I/==========>: onClick
0代表Down 2代表Move 3代表UP
因为我点击按钮的时候手抖了一下,所以才会出现两个2… 但是我们通过log事件的顺序可以看出执行方法的顺序是:
dispatchTouchEvent=>onTouch=>onTouchEvent=>onClick
为什么呢? 我们来看下dispatchTouchEvent方法的源码,方法里代码很多我们只看有用的:
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;
}
mOnTouchListener 这个是我们setOnTouchListener(new View.OnTouchListener() )传入的TouchListener. mViewFlags & ENABLED_MASK == ENABLED这个是描述button是否能够点击,
li.mOnTouchListener.onTouch(this, event)这个就是我们在onTouch()方法返回值.所以我们通过参数就可以看到,当li.mOnTouchListener.onTouch(this, event)返回true, 就不能执行onTouchEvent了就会变成这样
09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent0
09-01 13:22:40.313 2985-2985/com.xu.startservice I/==========>: onTouch0
09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent2
09-01 13:22:40.334 2985-2985/com.xu.startservice I/==========>: onTouch2
09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: dispatchTouchEvent1
09-01 13:22:40.354 2985-2985/com.xu.startservice I/==========>: onTouch1
所以onTouch()方法的级别比onTouchEvent()高,它的返回值决定onTouchEvent()是否执行.