ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Android事件分发

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会⾃动对后续的新事件序列启⽤拦截机制。onBackPressedDispatcherOnBackPressedDispatcher是 Android Jetpack 中用来处理‌返回键事件‌的工具主要用来替代废弃的Activity.onBackPressed()让 Fragment、Dialog 等组件也能方便地拦截或自定义返回逻辑。‌‌‌
返回列表