Primeton Mobile中Android的事件冒泡机制

4年前

有html开发经验的同学都知道dom的事件机制是从子到父,一层层冒泡,如果哪一层设置了cancelBubble=true,那这个事件就不再冒下去了,其它层不会响应这个事件。但在Android上的事件机制与html的不完全一样。


简单的说,Android的事件传递分为两个过程,第一个过程是从父到子,第二个过程是从子到父。


事件分发:public boolean dispatchTouchEvent(MotionEvent ev)


当有监听到事件时,首先由Activity的捕获到,进入事件分发处理流程。无论是Activity还是View,如前文所说,事件分发自身也具有消费能力,


如果事件分发返回true,表示改事件在本层不再进行分发且已经在事件分发自身中被消费了。至此,事件已经完结。如果你不想Activity中的任何控件具有任何的事件消费能力,


最简答的方法可以重写此Activity的dispatchTouchEvent方法,直接返回true就ok。


如果事件分发返回 false,表明事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费。


当然了,如果本层控件已经是Activity,那么事件将被系统消费或处理。


如果事件分发返回系统默认的 super.dispatchTouchEvent(ev),事件将分发给本层的事件拦截onInterceptTouchEvent 方法进行处理


(如果本层控件是Activity,由于其没有事件拦截,因此将直接将事件传递到子View,并交给子View的事件分发进行处理)。


事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev)


如果 onInterceptTouchEvent 返回 true,则表示将事件进行拦截,并将拦截到的事件交由本层控件 的 onTouchEvent 进行处理;


如果返回结果是false;则表示不对事件进行拦截,事件得以成功分发到子View。并由子View的dispatchTouchEvent进行处理。


如果返回super.onInterceptTouchEvent(ev),事件默认不会被拦截,交由子View的dispatchTouchEvent进行处理。


事件响应:public boolean onTouchEvent(MotionEvent ev)


如果onTouchEvent返回true,表示onTouchEvent处理完事件后消费了此次事件。此时事件终结,将不会进行后续的冒泡。


如果onTouchEvent返回false,事件在onTouchEvent中处理后继续向上层View冒泡,且有上层View的onTouchEvent进行处理。


如果返回super.onTouchEvent(ev),则默认处理的逻辑和返回false时相同。


总结:从以上过程中可以看出,dispatchTouchEvent无论返回true还是false,事件都不再进行分发,


只有当其返回super.dispatchTouchEvent(ev),才表明其具有向下层分发的愿望,


但是是否能够分发成功,则需要经过事件拦截onInterceptTouchEvent的审核。事件是否具有冒泡特是由onTouchEvent的返回值决定的。



整个过程中发现有两个奇怪的特点:


一.第一个过程中如果哪个父控件响应了事件,那么他的子控件就再也想应不到事件了。


二.如果哪一个子控件响应pressdown事件后,那之后的move,pressup事件都会直接发送给这个控件,不会再走分发的过程。

COMMENTS

需要 后方可回复
如果没有账号可以 一个帐号。