简单直观易理解的安卓事件分发机制
事件分发是安卓里面的重点和难点,也是面试经常会问到的问题,固对事件分发的流向和原理进行归纳和总结,力求做到简单直观明了。
概述
事件分发的传递流程是从上往下,一般情况下不做处理,传递流程是从Activity到父控件再到子控件,然后再往上传递回去,如果在哪一层消费掉了,就不再向上或向下传递。不同的事件,ActionDown和ActionUPActionMove是有区别的,所以下面分开来讲述。
ActionDown的事件分发
首先上一张网上的事件分发流程图,便于大家直观的感受:
控制传递的三个return,true,false,super。其中super代表调用父类的实现,也就是默认的传递方式。
消费的意思就是事件不再继续传递了,也可以说当前位置捕捉了这一事件。
Activity,ViewGroup,View共有的方法是dispatchtouchevent和ontouchevent,而onintercepttouchevent是ViewGroup特有的方法,用来决定是是否把事件传递给子View。
从上往下说,首先是Acitivty,事件首先传到这里,然后由Acitivty的dispatchtouchevent来分发,要注意的是这里return true或者false都会消费掉,只有super才会分发给下面的Viewgroup,然后由Viewgroup的dispatchtouchevent来分发,在这个方法里,return true会消费掉,return false则传递给上一层的onTouchEvent方法。ViewGroup的super会传递给onintercepttouchevent方法决定父VIew是否拦截,在这里返回true,则拦截,事件分发给当前Viewgroup的ontouchevent,不再向子View传递。如果返回false或者super,则继续向下传递给子VIew,由子view的dispatchtouchevent决定是否消费还是向上传递给父VIew的onTouchEvent或者交给自己的onTouchEvent方法处理。至于onTouchEvent的返回,true都是消费,返回false和super都是将事件传递给上一层的onTouchEvent。
总结下规律,对于dispatchtouchevent,除了acitvity的比较特殊,返回truefalse都是消费,在VIew和Viewgroup里面,返回true则消费,false则传递给上一层的ontouchevent,super则交给本层的ontouchevent处理。对于ontouchevent方法,返回true都是消费,false和super则是传递给上一层的ontouchevent。
只要了解了传递流程,配合图片,这套规律还是很容易理解的。
ActionMove、ActionUp的事件分发
这两个也叫后续事件,跟ActionDown不同,ActionUPActionMove后续事件的传递,是直接到达消费掉的那一层的。可以对比下,假设ActionDown事件从Acitivty传递到ViewGroup1,在传给其中的子ViewGroup2,然后再向上传递给ViewGroup2,并在ViewGroup2的ontouchevent里面消费掉了。而后续事件的传递,是直接从Acitvity传到ViewGroup1,然后从dispatchtouchevent、onintercepttouchevent、onTouchEvent依次传递,不再向下层View传递再传上来。也可以说,直接到达消费层,所以在消费层下面层的传递方法中,只能收到ActionDown事件,收不到ActionUP、ActionMove事件。
应用
熟悉了两种事件分发的传递流程,就可以在多层嵌套的布局里,根据不同的需求,在不同的方法里进行事件传递控制,或是处理事件。可以通过上面的三个方法和子View的requestDisallowInterceptTouchEvent方法,通过不同的返回值设置来控制事件的传递后走向。