事件体系中最重要的当属事件分发机制:
事件分发机制,堪称精髓的伪代码
dispatch(ev)
boolean consume=false;
if (onIntercept(ev))
consume = onTouchEvent(ev);
else
consume = child.dispatch(ev);
dispatchTouchEvent + onInterceptTouchEvent + onTouchEvent
-
dispatchTouchEvent
用于事件分发。如果事件能够传递给当前的view,那么这个方法必然调用,它的返回值受当前View的onTouchEvent和下一级view的dispatchTouchEvent方法影响,表示是否消耗当前事件 -
onInterceptTouchEvent
在上述方法内部调用,用来判断是否拦截某个事件,如果当前view拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件; -
onTouchEvent
依旧在dispatchTouchEvent内部调用,用来处理事件,返回值表示是否消耗当前事件。
如果不消耗,那么在同一个事件序列中,当前view无法再次接收到事件;
事件序列:MotionEvent 内部状态 一次点击事件一次触摸事件整个流程
传递 从activity---->window---> view --->window--->activity 如果都没有处理逆向返回。涉及
这里涉及一个小知识点,activity包含phoneWindow,phoneWindow包含DectorView。详见前面window相关的文章
requestDisallowInterceptTouchEvent
方法可以在子view中干预父view的事件分发过程,但是ACTION_DOWN事件除外;这是因为ACTION_DOWN的时候会重置标志位,因此无法干预这个状态;
总结性的点放在前面,细节需要扣源码,且往下看;
onTouchListener 优先于 onTouchEvent 优先于 onClick
如果一个view一旦决定拦截,那么这个事件序列都只能由它来处理,并且它的Intercept事件不再调用。所以如果要确保每次都能调用,在dispatch中处理;
如果view开始处理事件,但是它不消耗ACTION_DOWN事件,那么同一事件序列的其他事件不会再交给它来处理;
如上我们可以做什么:
- 清楚事件分发机制,设计业务,更有效的拆分需求,实现功能
View 自定义控件
未完待续...
网友评论