二、ViewGroup | dispatchTransformedTouchEvent 完整流程分析
如果事件被拦截 , 或者没有被消费掉 , 则不会对 mFirstTouchTarget 进行初始化 , mFirstTouchTarget 为空 ;
ViewGroup | dispatchTransformedTouchEvent 方法中 ,
传入的子组件为空 , 表示事件被拦截了 , 或消费不成功 , 此时需要消费自己的触摸事件 , 调用父类 View 的 dispatchTouchEvent 方法就是消费自己的触摸事件 ;
传入的子组件不为空 , 则将事件传递给子组件 ;
/** * Transforms a motion event into the coordinate space of a particular child view, * filters out irrelevant pointer ids, and overrides its action if necessary. * If child is null, assumes the MotionEvent will be sent to this ViewGroup instead. * 该方法是正式分发触摸事件的方法 * 注意参数中传入了当前正在被遍历的 child 子组件 * 如果事件被拦截 , 或者没有被消费掉 , 则不会对 mFirstTouchTarget 进行初始化 , mFirstTouchTarget 为空 */ private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel, View child, int desiredPointerIdBits) { final boolean handled; // Canceling motions is a special case. We don't need to perform any transformations // or filtering. The important part is the action, not the contents. // 处理取消状态 , 暂时不分析 ; final int oldAction = event.getAction(); if (cancel || oldAction == MotionEvent.ACTION_CANCEL) { event.setAction(MotionEvent.ACTION_CANCEL); if (child == null) { // 传入的子组件为空 // 表示事件被拦截了 / 或消费不成功 // 消费自己的触摸事件 , 调用父类 View 的 dispatchTouchEvent 方法就是消费自己的触摸事件 handled = super.dispatchTouchEvent(event); } else { // 组件不为空 , 则将事件传递给子组件 handled = child.dispatchTouchEvent(event); } event.setAction(oldAction); return handled; } }
三、View | dispatchTouchEvent 完整流程分析
View | dispatchTouchEvent 方法中 , 会调用 View 的 OnTouchListener 方法 , OnTouchListener 是在 View 的 ListenerInfo mListenerInfo 成员中的 OnTouchListener mOnTouchListener 成员 ;
这是用户设置的 触摸监听器 , 是开发时设置的组件的触摸事件 , 返回 true / false ;
如果返回 true 则成功消费事件 , 事件分发到此结束 ;
如果返回 false , 则事件继续向下传递 ;
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { public boolean dispatchTouchEvent(MotionEvent event) { if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) { result = true; } //noinspection SimplifiableIfStatement // 设置的 触摸监听器 就是封装在该对象中 ListenerInfo li = mListenerInfo; // 判断该组件是否被用户设置了 触摸监听器 OnTouchListener if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED // 执行被用户设置的 触摸监听器 OnTouchListener && li.mOnTouchListener.onTouch(this, event)) { // 如果用户设置的 触摸监听器 OnTouchListener 触摸方法返回 true // 此时该分发方法的返回值就是 true result = true; } } }
源码路径 : /frameworks/base/core/java/android/view/View.java