一张图看透Android事件传递机制

一、引言

总觉得知识必须要总结,不然就算再熟悉的东西,一段时间不接触就容易遗忘;上次给一个朋友解释回调的时候就有深刻的体会,所以现在养成总结的习惯,而我觉得最直观的方法就是图解,所以就有了下面的图,通过这张图看透Android事件传递机制;

PS:有时候自己的理解可能也存在问题,所以通过这种形式能够得到大家的审查和修改意见,在这里先谢谢大家了!

二、就是这张图(自己看了一下,这张图看不清楚,复制或保存本地,使用图片查看器放大查看;或者点击链接查看原图)

查看高清原图:一张图看透Android事件传递机制

三、图片局部细节详解1.Touch事件的传入 :

开始由UserActivity(用户自定义的Activity)接收到事件,这个类继承自Activity,没有onInterceptTouchEvent方法(为什么没有?谁能给我一个合理的解释吗?)

事件传递到disPatchTouchEvent,这里默认的是调用父类的disPatchTouchEvent,查看父类的源码可以看到,

/*** Called to process touch screen events. You can override this to* intercept all touch screen events before they are dispatched to the* window. Be sure to call this implementation for touch screen events* that should be handled normally.** @param ev The touch screen event.** @return boolean Return true if this event was consumed.*/public boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {onUserInteraction();}if (getWindow().superDispatchTouchEvent(ev)) {return true;}return onTouchEvent(ev);}

这里的第一个判断条件中方法的执行为为空实现:

第二个判断中的判断条件是有窗体事件分配决定的,窗体默认的事件分发机制,再往里面看,如下代码 /*** Used by custom windows, such as Dialog, to pass the touch screen event* further down the view hierarchy. Application developers should* not need to implement or call this.**/public abstract boolean superDispatchTouchEvent(MotionEvent event); 可以理解为Android系统自己定义的事件分发机制,上面说明了应用开发者不需要去实现或者调用这个方法。我理解的是系统已经为你准备好了普通窗口事件该如何分发,不需要你再手动去修改这块代码了!如果你不按照我的方法来做,那么好吧,后面的事你都自己干吧,就是这么任性。所以在UserActivity中手动修改dispatchTouchEvent方法的返回值,就会使本次事件被消费掉,不再向里层传递。

顺带看看onTouchEvent方法吧:

/*** Called when a touch screen event was not handled by any of the views* under it. This is most useful to process touch events that happen* outside of your window bounds, where there is no view to receive it.** @param event The touch screen event being processed.** @return Return true if you have consumed the event, false if you haven't.* The default implementation always returns false.*/public boolean onTouchEvent(MotionEvent event) {if (mWindow.shouldCloseOnTouch(this, event)) {finish();return true;}return false;}

从上面的说明可以看出,当触屏事件没有被内层所有的view处理的时候才会被调用;当处理你窗体外没有任何view处理的Touch事件的时候最有用。

从返回值说明可以看出,默认返回值通常为false,所以一般如果事件不被子view消费,事件一般都会被舍弃掉

2.从Activity中传入外层的ViewGroup中

经过了UserActivty后传入到ViewParent中来,第一个走的肯定还是dispatchTouchEvent,依然,如果手动修改dispathTouchEvent的返回值,本次事件就到此为止。如果使用父类(ViewGroup)的事件分发机制,那么事件就会首先传递到onInterceptToucEvent中来;(这部分里面代码太多,我想你也没兴趣看;万一你是个Geek,那你也可以自己去扒一扒源码,自己阅读一下,这里就不再详细介绍了,本文就是为了言简意赅的说明Touch事件的传递机制,所以见谅)

在onInterceptTouchEvent中,就会询问你“你想不想拦截本次事件啊?”

|–“想”(return true),那么事件就会进入自己的onTouchEvent中执行

那么事件就会到了onTouchEvent中,这时系统就会问你:“你想不想处理这次点击事件啊?”

|–“想”(return true)那么本次事件被消费掉了

|–“不想”(return false)那么他就会认为你里层的子控件都不想接收本次事件,那他直接把本次事件往回传递(传回UserActivty中去处理)。需要注意的是,如果本次事 件是DOWN事件,那么本次的MOVE、UP也将不会传递到ViewParent中来了,注意是本次哦,仅仅只是指你一次按下到抬起这一套动作,还有第二次,第三次,还是要来的。

如果没法忘记他,就不要忘记好了。真正的忘记,是不需要努力的。

一张图看透Android事件传递机制

相关文章:

你感兴趣的文章:

标签云: