Android 事件分发学习笔记
在Android 触摸事件分发中,分别记录下Down事件 和 UP事件以及MOVE事件
down事件:从Activity -dispatchTouchEvent()方法开始通过phoneWindow对象传递到DecorView,DecorView是一个Framelayout,Framelayout继承ViewGroup,所以事件就从ViewGroup分发开始了。如果是down事件 或者是 targetView(个人理解是ontouchEvent方法中返回ture的对象, 或者说ViewGroup中的有View或者ViewGroup想要消耗down事件的对象构成的一个链表)不为空 就会去判断ViewGroup是否要拦截事件down事件 会一直分发下去,知道最后一个view调用onTouchEvent()方法。如果所有的view和ViewGroup的onTouchEvent()都返回false,最后会调用Activity的onTouchEvent()方法。
up 事件 :首先从Activity开始分发到Framelayout的dispatchTouchevent()方法,如果Framelayout的targetView是null,就是在down事件中没有View或者ViewGroup想消费事件,则直接返回给activity处理。up事件会分发到有targetView的viewgroup层次。如果DecorView 中没有targetView,就不会分发下去,直接返回给activity,假设说有5层view,第三层view 有能消费的View,就会分发到第三层,第四层第五层不再接收到分发事件。
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
mOnTouchListener 的优先级要比onTouchEvent()方法高,在onTouchEvent()方法中针对up down 和 move事件做了处理
up事件中才有可能去执行onClick事件,
Android开发艺术探索中对滑动冲突的处理
主要是调用了拦截方法,即ViewGroup事件在down 和 up事件中不拦截,在move过程中去拦截所需要的事件,
还有一个是方案是ViewGroup不去拦截事件,view在不需要处理的事件事通过view.getPatent.requestDisallowInterceptTouchEvent(false)请求不允许拦截标志位false,即需要父容器拦截事件,这样view收不到move事件,viewgroup有机会拦截,调用viewgroup的onTouchEvent()事件。
MainActivity dispatchTouchEvent down activity分发到viewgroup
FirstLayout dispatchTouchEvent down viewgroup分发事件
FirstLayout onInterceptTouchEvent down 判断是否要拦截
FirstLayout onTouchEvent down 执行touchEvent,返回结果是false
MainActivity onTouchEvent down 返回给activity 处理touch事件
MainActivity dispatchTouchEvent up up事件分发 target = null,不分发事件
MainActivity onTouchEvent up
MainActivity dispatchTouchEvent down
FirstLayout dispatchTouchEvent down
FirstLayout onInterceptTouchEvent down
SecondLayout dispatchTouchEvent down
SecondLayout onInterceptTouchEvent down
SecondLayout onTouchEvent down
FirstLayout onTouchEvent down
MainActivity onTouchEvent down
MainActivity dispatchTouchEvent up
MainActivity onTouchEvent up
MainActivity dispatchTouchEvent down
FirstLayout dispatchTouchEvent down
FirstLayout onInterceptTouchEvent down
SecondLayout dispatchTouchEvent down
SecondLayout onInterceptTouchEvent down
TestButton dispatchTouchEvent down
TestButton onTouchEvent down
MainActivity dispatchTouchEvent up
FirstLayout dispatchTouchEvent up
FirstLayout onInterceptTouchEvent up
SecondLayout dispatchTouchEvent up
SecondLayout onInterceptTouchEvent up
TestButton dispatchTouchEvent up
TestButton onTouchEvent up