直接来总结
附上本人总结的表格(已用代码验证)
enabled | clickable | onTouchListener是否会被调用 | onTouchListener#onTouch返回值 | onClickListener是否会被调用 | onTouchEvent返回值 | dispatchTouchEvent返回值 |
---|---|---|---|---|---|---|
true | true | 是 | true | 否 | true | true |
true | true | 是 | false | 是 | true | true |
true | false | 是 | true | 否 | true | true |
true | false | 是 | false | 否 | false | false |
false | true | 否 | - | 否 | true | true |
false | false | 否 | - | 否 | false | false |
- 只要
view
是enabled
,onTouchListener
就会被调用 - 只有
view
是enabled
且可点击(clickable
、longClickable
、contextClickable
任意一种),且onTouchListener
返回false
,onClickListener
才会被调用 - 如果
onTouchListener
没有消耗事件,且是可点击的(三种情况),那么无论设不设置onClickListener
也无论其返回值是什么,此事件都会被消耗,因为View
的onTouchEvent
对事件进行了默认处理
不设置
onTouchListener
或onClickListener
相当于返回false
dispatchTouchEvent
返回值是为了分析父子View
事件分发,表示触摸事件是否被消费
分析
触摸事件(TouchEvent)分发的起始点为Activity#dispatchTouchEvent(MotionEvent event)
,上一层就是Native层了
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
//先给Window处理,里面再给DecorView处理,再是ViewGroup,然后分发给各个View或ViewGroup
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
//如果没有人处理,最后自身的onTouchEvent作为兜底事件
return onTouchEvent(ev);
}
onTouchListener与onTouchEvent以及enable的影响
在View#dispatchTouchEvent(MotionEvent event)
中有如下代码