事件分发中的onTouch 和onTouchEvent 有什么区别?

当看到这两个方法时,我们大概就应该直到 onTouchEvent 是触摸反馈的事件, onTouch 为一个方法。

像这种写法,我们经常看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//onTouch 方法
layout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//返回值尤为重要,如果父控件设置了此方法并返回true,就不会再继续向下传递
return false;
}
});
//onTouchEvent 方法
public class MyView extends View {
....

@Override
public boolean onTouchEvent(MotionEvent event) {
//分别处理事件的按下,移动,抬起等操作
return super.onTouchEvent(event);
}
}

我们直到事件的传递分发从 diapatchTouchEvent() 方法开始,可以看下该方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public boolean dispatchTouchEvent(MotionEvent event) {
...
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
//这里判断是否设置了onTouchListener,控件是否可用,onTouch的返回值
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
//判断onTouchEvent 的返回值
if (!result && onTouchEvent(event)) {
result = true;
}
...
}

可以看到,程序优先判断了设置了 onTouchListener ,然后再判断 onTouchEvent, 即判断的先后顺序不同。

在前面我们说到,如果设置了 onTouchListener 并且在重写 onTouch 方法中返回了 true ,表明消费这个控件的触摸事件,那么该控件的点击事件将无法收到,因为点击事件 performOnClick 是在 onTouchEvent() 方法中执行的,如下:

1
2
3
4
5
6
7
8
9
10
11
public boolean onTouchEvent(MotionEvent event) {
switch (action) {
case MotionEvent.ACTION_UP:
...
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClickInternal();
}
}
-------------本文结束感谢您的阅读-------------