为什么Android中onTouchListener未设置onClickListener时收不到ACTION_UP事件
问题原因
该现象是Android View触摸事件分发机制与View默认属性共同作用的结果,具体逻辑如下:
ConstraintLayout作为普通ViewGroup,默认clickable、longClickable属性均为false。View.onTouchEvent源码固有逻辑:只有当View的clickable/longClickable/contextClickable任意一个属性为true时,onTouchEvent才会返回true表示消费触摸事件,否则直接返回false。- Android触摸事件分发规则:触摸事件按完整序列从
ACTION_DOWN开始,到ACTION_UP结束。如果某个View处理ACTION_DOWN时返回false表示不消费该事件序列,后续的所有事件(包括ACTION_MOVE、ACTION_UP、ACTION_CANCEL)都不会再分发给该View。
未设置OnClickListener时的执行流程
此时ConstraintLayout的clickable为false,onTouchEvent返回false:
ACTION_DOWN事件到达时,会先回调你设置的OnTouchListener,所以你能打印到DOWN事件的日志。随后onTouchListener返回view.onTouchEvent(event)也就是false,系统判定你不消费该事件序列,后续所有事件不会再传递给这个ConstraintLayout,所以你收不到ACTION_UP。
你提到按住2-3秒才观测不到UP事件,是因为短按场景下UP事件触发极快,部分ROM的事件调度逻辑存在微小差异,核心本质还是事件序列不再分发给目标View。
设置空OnClickListener时的执行流程
调用setOnClickListener方法时,源码内部会自动将View的clickable属性置为true,和onClick方法内是否有实现逻辑无关:
- 此时
onTouchEvent返回true表示消费ACTION_DOWN事件,系统会将该事件序列的所有后续事件都继续分发给该View,所以你可以正常收到ACTION_UP。
你也可以直接调用clSend.setClickable(true)替代设置空OnClickListener,效果完全一致。
内容的提问来源于stack exchange,提问作者Tahmm
相关产品推荐
相关产品推荐

