1、基础知识
(1) 所有Touch事件都被封装成了MotionEvent对象,包括Touch的位置、时间、历史记录以及第几个手指(多指触摸)等。
(2) 事件类型分为ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以ACTION_DOWN开始ACTION_UP结束。
(3) 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和OnTouchListener
2、传递流程
(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。
(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。
(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数。
(4) 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来。
(5) OnTouchListener优先于onTouchEvent()对事件进行消费。
上面的消费即表示相应函数返回值为true。
3、事件传递机制流程图
(1) View不处理事件流程图:
view-ignore-touch-event-example
View处理事件流程图:
view-process-touch-event-example
(2)事件分发:public boolean dispatchTouchEvent(MotionEvent ev)
当有监听到事件时,首先由Activity的捕获到,进入事件分发处理流程。无论是Activity还是View,事件分发自身也具有消费能力。
如果事件分发返回true,表示该事件在本层不再进行分发且已经在事件分发自身中被消费了。至此,事件已经完结。如果你不想Activity中的任何控件具有任何的事件消费能力,
最简答的方法可以重写此Activity的dispatchTouchEvent方法,直接返回true就ok。
如果事件分发返回 false,表明事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费。
当然了,如果本层控件已经是Activity,那么事件将被系统消费或处理。
如果事件分发返回系统默认的 super.dispatchTouchEvent(ev),事件将分发给本层的事件拦截onInterceptTouchEvent 方法进行处理。
<从分析中可以看出,dispatchTouchEvent无论返回true还是false,事件都不再进行分发,只有当其返回super.dispatchTouchEvent(ev),才表明其具有向下层分发的愿望>
(3)事件拦截过程:public boolean onInterceptTouchEvent(MotionEvent ev)
如果onInterceptTouchEvent返回true,则表示将事件进行拦截,
并将拦截到的事件交由本层控件的onTouchEvent 进行处理;
如果返回结果是false;则表示不对事件进行拦截,事件得以成功分发到子View。
并由子View的dispatchTouchEvent进行处理。
如果返回super.onInterceptTouchEvent(ev),事件默认不会被拦截,
交由子View的dispatchTouchEvent进行处理。
过程图如下:
(4)事件响应:public boolean onTouchEvent(MotionEvent ev)
如果onTouchEvent返回true,表示onTouchEvent处理完事件后消费了此次事件。此时事件终结,将不会进行后续的冒泡 也就是说不会再将事件传递到上层View的onTouchEvent处理。
如果onTouchEvent返回false,事件在onTouchEvent中处理后继续向上层View冒泡,且有上层View的onTouchEvent进行处理。
如果返回super.onTouchEvent(ev),则默认处理的逻辑和返回false时相同。
说明:本文转载自:http://www.trinea.cn/android/touch-event-delivery-mechanism/
向前辈致敬、向前辈学习... ...
扩展:相关阅读
在ViewGroup中处理Touch Events:
http://yanghui.name/blog/2013/10/17/managing-touch-events-in-a-viewgroup/