Android事件分发机制
1:事件从最底层的Activity开始分发
2:伪代码:Activity->ViewGroup->View
本质:从Activity开始,层层递归分发事件,到最顶层的View的onTouchEvent判断是否消费事件。
事件分发是从Activity到View,但是onTouchEvent的执行判断,是从View到Activity。
//Activity public boolean dispatchTouchEvent(MotionEvent event) { if (dispatchTouchEventViewGroup(event)) {//如果事件没有在子view消费掉,依然会到自身的onTouchEvent执行 return true;//事件被消费 } return onTOuchEvent(event); } //ViewGroup public boolean dispatchTouchEventViewGroup(MotionEvent event) { boolean result; if (interceptTouchEvent()) { result = onTouchEvent(); } else { if (dispatchTouchEventView(event)) { return true;//被消费 } else { result = onTouchEvent();//View的onToucheEvent返回false,事件没有被view消费,执行Activity的onTouchEvent } } return result; } //View public boolean dispatchTouchEventView(MotionEvent event) { return onTouchEvent();//事件消费,返回true }
3:down事件的处理
如果一个子view处理了down事件,也就是返回了true,那么后续的move和up事件都会分发给这个子view处理。
如果这个子view返回false,大概率是这个子view不可点击,那么就会由别的子view或者父类的ViewGroup消费这个事件那么后续的move和up也就不会再派发给这个子view。所以准确的说法应该是如果某个子view,对down事件返回false,那么move和up事件就不会再派发给这个子view,而不是说move和up事件不会再执行。
4:滑动冲突:
ViewGroup默认不拦截事件,都交给子View处理,所以就会出现ViewPager内部嵌套RecyclerView,只有RecyclerView可以滑动,ViewPager无法滑动。如果ViewPager改为拦截down事件,那么move和up都不会再向下传递,这个时候又会出现新的问题,就是ViewPager可以滑动,但是RecyclerView不能滑动。
所以,解决办法是ViewPager只拦截水平方向的move事件,down、up和垂直方向的move都不拦截。