@[toc]
何为事件分发
- 基础知识
事件:MotionEvent(点击事件)
事件列:从手指接触屏幕至手指离开屏幕的这个过程所产生的一系列事件,一般情况下,点击事件都是从DOWN事件开始,UP事件结束,中间经历若干个MOVE事件。
事件类型: 手指按下 -->产生DOWN事件 手指滑动 -->产生MOVE事件 手指抬起 -->产生UP事件
- 定义理解:一般来说,事件分发就是将点击事件分发(可以理解为传递)到一个view去处理该事件。
ACTION_DOWN事件怎么传递和处理的
看了不少文章,po一张比较好理解的图:基于ACTION_DOWN事件走向。 来源Kelin
先对这图做一些基本说明:
- true---该控件或activity消费事件,事件不再被传递。
- false---该控件或actiivty不消费事件,事件被继续传递。
- super---调用该方法的父类实现,在方法中可修改返回值。
- dispatchTouchEvent()---事件首先到达的方法。用于分发点击事件,一般不会重写这个方法。
- onInterceptTouchEvent()---判断是否拦截该事件,用来拦截事件。
- onTouchEvent()---判断是否消费该事件,用来处理事件。
上图很明显地表示了系统默认的对于down事件的传递方式。我们可以观察到这些事件在三个对象间进行传递,分别是activity,viewgroup,view。 总结: activity层的dispatchTouchEvent()---调用--->activity层父类的dispatchTouchEvent()(默认实现是调用viewgroup层的dispatchTouchEvent())---调用--->super的默认实现 viewgroup层onInterceptTouchEvent()---调用--->【默认返回false】super的默认实现view层dispatchTouchEvent()---调用--->super的默认实现view层的onTouchEvent()
在这之后,如图,默认情况下,view层和Viewgroup都不进行消费,那么就会一路传给了activity层的onTouchEvent()进行消费。 于是出现了类似U型的流程走向。
po另外一张图,来源还是 Kelin 注:右上角的横线表明返回值 我们可以很清楚地看到整个的流程,有几点总结一下
1.只有viewgroup才有 onInterceptTouchEvent()方法。
2.当viewgroup层的 onInterceptTouchEvent()返回值为true,表明该viewgroup想要处理这个事件,那么这个事件便会传递给其onTouchEvent()进行处理。
3.如果onTouchEvent()或者dispatchTouchEvent()不想处理事件,返回false,则抛给上级的onTouchEvent()进行处理。
4.另外,调用优先级: onTouchListener的onTouch>View的onTouch>onClickListener 当一个view需要处理事件时,如果它设置了onTouchListener,那么onTouchEvent()中的onTouch()会被回调。如果该方法返回值为true,那么当前view的onTouchEvent()将不会被调用,返回false才会调用到view的onTouchEvent()。这个时候再onTouchEvent()中设置的onClickListener()才会被调用。
ACTION_MOVE和ACTION_UP事件怎么传递和处理的
详细可参考博客中的参考图片及相关说明。此处不再赘述,只做总结。
- 总结
- 1.当一个view决定拦截一个事件后,系统会把同一个事件系列内的所有事件都交给他处理,此时不需要再调用拦截器询问是否需要拦截。因此同一个事件系列中的事件一般也只由一个view进行处理。
- 2.在DOWN事件发生时,如果某个view的onTouchEvent()被调用,但是返回了false[即不想处理],那么该事件系列后续的事件也不再传递给他,乃是传给其父类viewgroup的onTouchEvent()。这一点的话很像是上级交给程序员一个任务,他没完成,交给他的上级完成。那么短时间内他的上级就不会交给他相关任务了。 这个时候我们可能会发现,其实事件分发的机制可以用领导交给下级任务这种职场常见模式进行分析,或许这样会更加容易理解。
- 3.在哪个对象的onTouchEvent()进行消费,那么后续的事件都会给其进行处理。
事件分发是第一次接触的东西,源码和实例等等还没有进行研究。若有错误之处,还望各位不吝赐教。