话说:只要掌握了事件分发机制,就能找到好工做、升职加薪、当上总经理、出任ceo、迎娶白富美。
哈哈哈,不啰嗦,让咱们开始。java
和事件分发机制密切相关的三个方法分别是:android
public boolean dispatchTouchEvent(MotionEvent ev)
git
用来进行事件的分发。若是事件可以传递到当前View,此方法必定会被调用,返回结果受当前View的onTouchEvent()
和下级View的diapatchTouchEvent()
方法的影响,表示是否消耗当前事件。github
public boolean onInterceptTouchEvent(MotionEvent event)
ui
用来判断是否拦截某个事件,若是当前View拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。spa
public boolean onTouchEvent(MotionEvent event)
code
在dispatchTouchEvent()
中调用,用来处理点击事件,返回结果表示是否消耗当前事件,若是不消耗,则在同一个事件序列中,当前View没法再次接收事件。orm
public boolean dispatchTouchEvent(MotionEvent event) { boolean consume = false; if(onInterceptTouchEvent(ev)) { consume = onTouchEvent(ev); } else { consume = child.dispatchTouchEvent(ev); } return consume; }
经过上面的伪代码,咱们大体能够了解点击事件的传递规则:对于一个根ViewGroup来讲,点击事件产生后,首先会传递给它,这是它的
dispatchTouchEvent()
就会被调用,若是这个ViewGroup的onInterceptTouchEvent()
方法返回true就表示它要拦截当前事件,接着事件就会交给该ViewGroup处理,即执行onTouchEvent()
方法。若是onInterceptTouchEvent()
方法返回false就表示它不拦截该当前事件,这时事件就会继续传递给它的子元素,接着子元素的dispatchTouchEvent()
就会被调用,如此反复,直到事件被处理。事件
同一个事件序列是指从手指触摸屏幕的那一刻起,到手指离开屏幕那一刻结束,在这个过程当中产生的一系列事件,这一系列事件以down事件开始,以up事件结束,中间可能有一些move事件。开发
正常状况下,一个事件序列只能被一个View拦截并消耗。
某个View一旦决定拦截,那么这一个事件序列都只能由它来处理(若是事件序列可以传递给它的话),而且它的onInterceptTouchEvent()
不会再被调用。
某个View一旦开始处理事件,若是它不消耗ACTION_DOWN事件(onTouchEvent()
返回了false),那么同一事件序列中的其余事件都不会再交给它处理,而且事件将从新交由它的父元素去处理,及父元素的onTouchEvent()
会被调用。
若是View不消耗ACTON_DOWN之外的其余事件,那么这个点击事件会消失,此时父元素的onTouchEvent()并不会被调用,而且当前View能够持续收到后续的事件。最终这些消失的点击事件会传递给Activity处理。
ViewGroup默认不拦截事件。onInterceptTouchEvent()
方法默认返回false。
View没有onInterceptTouchEvent()
方法,一旦有事件传递给它,那么它的onTouchEvent()
方法就会被调用。
View的onTouchevent()
默认都会消耗事件(返回true),除非它是不可点击的(clickable和longClickable同时为false)。
View的enable属性不影响onTouchEvent()
的默认返回值。哪怕一个View是disable状态的,只要它的clickable和longClickable有一个为true,那么它的onTouchEvent()
就返回true。
onClick会发生的前提是当前View是可点击的,而且它收到了down和up的事件。
事件传递的方向是由外向内的,即事件老是先传递给父元素,而后由父元素分发给子View。
当面对ACTION_DOWN事件时,ViewGroup老是会调用本身的onInterceptTouchEvent()
方法来询问本身是否要拦截该事件。
当ACTION_UP方法发生时,会触发performClick()
方法,若是View设置了onClickListener,那么performClick()
方法内部会调用它的onClick()方法。
为了把事件分发机制研究明白,我画了一张流程图。
就到这里了。
若是有什么问题,你们能够在评论中提出来,咱们一块儿讨论。
加油,各位!
本文来自:http://qiaoyunrui.github.io/2016/05/23/androidDispatchEvent/