Android事件分发

android 事件响应机制是先分发再处理。分发是先由外部的View接收,然后依次传递给其内层的最小View,从最小View单元(事件源)开始处理,依次向外层传递。

Android事件分发的三个基本方法

  • dispatchTouchEvent:事件分发
  • onInterceptTouchEvent:事件拦截(只有ViewGroup中有)
  • onTouchEvent:事件处理

这三个方法的调用顺序是dispatchTouch分发->onInterceptTouch拦截->onTouch处理,在dispatchTouchEvent中调用onInterceptTouchEvent和onTouchEvent,即dispatch中调用on。

具体是先调用onTouchListener,再判断调用onTouchEvent。onTouchListener优先调用即开发者定义的事件优先调用。

onTouchListener返回值依旧表示事件是否被消费。注意只有当ACTION_DOWN事件返回true即被消费、不被忽略时,后续的Action才会被执行。

分发过程

dispatchTouchEvent方法负责把事件分发给自己或其子元素。

在事件传递给ViewGroup后,ViewGroup的dispatchTouchEvent会被调用,其中会调用自己的onInterceptTouchEvent拦截方法:

  • 如果onInterceptTouchEvent返回true则表示自己拦截事件,接着调用自己的onTouchEvent。
  • 如果onInterceptTouchEvent返回false则表示自己不拦截事件,接着调用子元素的dispatchTouchEvent,直到事件在子元素中被拦截。ViewGroup默认是不拦截事件,继续向下传递事件。

dispatchTouchEvent的返回值是onTouchEvent的返回值或子元素的dispatchTouchEvent的返回值,表示是否被消费。

dispatchTouchEvent分发调用的方向是从父向子依次遍历调用。

消费过程

onTouchEvent处理调用的顺序则是从子向父依次回溯调用。

几个事件接口方法的优先级高低顺序

onTouchListener >>> onTouchEvent >>> onLongClickListener >>> onClickListerner

滑动冲突解决方式

  • 外部拦截法 —— 重写父容器的onInterceptTouchEvent方法;在父容器的onInterceptTouchEvent方法中,首先ACTION_DOWN事件父容器必须返回false,即不拦截ACTION_DOWN事件,因为如果父容器拦截了ACTION_DOWN,后续的ACTION_MOVE/ACTION_UP都将会交给父容器处理;其次是ACTION_MOVE,根据需求决定是否要拦截;最后ACTION_UP事件,必须要返回false,即不拦截ACTION_UP事件。
  • 内部拦截法 —— 所有事件都传递给子元素,如果子元素需要就消耗掉,不需要就交给父元素处理。需要子元素配合调用requestDisallowInterceptTouchEvent方法才能正常工作;父元素需要默认拦截除ACTION_DOWN以外的事件,这样子元素调用parent.requestDisallowInterceptTouchEvent(false)方法时,父元素才能继续拦截需要的事件。(ACTION_DOWN事件不受requestDisallowInterceptTouchEvent方法影响,如果父元素拦截ACTION_DOWN事件,那么所有事件都无法传递到子元素去)。

getParent().requestDisallowInterceptTouchEvent(true)

这个⽅法传递true时会递归通知每⼀级⽗View,让它们在本事件后续序列中不要再尝试通过onInterceptTouchEvent()拦截事件。这个通知仅在当前事件序列有效,即在这组事件结束(⽤户抬⼿)后,⽗View会⾃动对后续的新事件序列启⽤拦截机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值