本文共 2464 字,大约阅读时间需要 8 分钟。
/** * View的事件分发 */public class View{ public boolean dispatchTouchEvent(MotionEvent ev){ boolean result = false; // 先判断是否设置了onTouchListener,如果设置了,就调用 if (mOnTouchListener != null && mOnTouchListener.onTouch(ev)) { result = true; } // 如果没有设置onTouchListener,或者调用了onTouch后返回了false,那么就调用onTouchEvent if (!result && onTouchEvent(ev)) { result = true; } return result; } public boolean onTouchEvent(MotionEvent ev){ // 如果View可点击 if (isClickable()) { switch (ev.getAction()) { ... case MotionEvent.ACTION_UP: ... // 判断是否设置了onClickListener,设置了就调用,并消耗事件 if (mOnClickListener != null) { mOnClickListener.onClick(this); } ... break; ... } // 可点击的View,默认会消耗掉事件 return true; } // 不可点击的View,默认不消耗事件 return false; }}
/** * ViewGroup的事件分发 */public class ViewGroup extends View{ // 一旦有子元素消耗了事件,这个子元素就被赋值给mFirstTouchTarget public View mFirstTouchTarget = null; public boolean dispatchTouchEvent(MotionEvent ev){ int action = ev.getAction(); boolean handled = false; boolean intercepted; // DOWN事件,或者有子元素消耗事件,则进入if语句内,判断是否拦截 if (action == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { // 取出 是否允许拦截 的标记,默认是false。子元素可以通过requestDisallowInterceptTouchEvent(true);将这个标记设置为true boolean disallow = getFlagDisallowIntercept(); if (!disallow) { // 允许拦截,调用onInterceptTouchEvent判断是否拦截 intercepted = onInterceptTouchEvent(ev); }else { // 不允许拦截,直接不拦截 intercepted = false; } }else { // 非DOWN事件,或者没有子元素消耗了事件,直接拦截 intercepted = true; } // 如果有子元素消耗事件,alreadyDispatched就被赋值为true boolean alreadyDispatched = false; if (!intercepted) { // 不拦截事件 // 遍历子元素 for (int i = 0 ; i < mChildList().size() ; i++) { View child = mChildList.get(i); float x = ev.getX(); float y = ev.getY(); if (x >= child.left && x <= child.right && y >= child.top && y <= child.bottom) { // 事件位于子元素所在区域内,将事件分发给子元素 if (child.dispatchTouchEvent(ev)) { // 子元素消耗了事件 mFirstTouchTarget = child; alreadyDispatched = true; // 跳出循环,不再分发 break; } } } } if (mFirstTouchTarget == null) { // 没有子元素消耗事件 // ViewGroup自行处理事件 super.dispatchTouchEvent(ev); }else { // 有子元素消耗了事件,则后续事件全部交给该子元素处理,不管他是否消耗事件 if (alreadyDispatched) { mFirstTouchTarget.dispatchTouchEvent(ev); handled = true; } } return handled; } public boolean onTouchEvent(MotionEvent ev){ super.onTouchEvent(ev); } public boolean onInterceptTouchEvent(MotionEvent ev){ return false; }}
转载地址:http://rdegi.baihongyu.com/