美文网首页
Android View事件分发机制

Android View事件分发机制

作者: dexteryu | 来源:发表于2017-10-07 21:58 被阅读0次

    Android View 事件分发机制

    // Activity.dispatchTouchEvent()
    public boolean dispatchTouchEvent(MotionEvent ev) {
            if (getWindow().superDispatchTouchEvent(ev)) {
                return true;
            }
            return onTouchEvent(ev);
    }
    // PhoneWindow.superDispatchTouchEvent()
    public boolean superDispatchTouchEvent(MotionEvent event) {
            return mDecor.superDispatchTouchEvent(event);
    }
    // DecorView.superDispatchTouchEvent()
    public boolean superDispatchTouchEvent(MotionEvent event) {
            return super.dispatchTouchEvent(event);
    }
    // ViewGroup.dispatchTouchEvent()
    public boolean dispatchTouchEvent(MotionEvent ev) {
            if (actionMasked == MotionEvent.ACTION_DOWN) {
                resetTouchState();// 重置FLAG_DISALLOW_INTERCEPT
            }
            /**
            1、ViewGroup不拦截事件 -> mFirstTouchTarget != null
            2、ViewGroup拦截事件   -> mFirstTouchTarget == null
            3、ViewGroup拦截事件   -> ACTION_MOVE和ACTION_UP的onInterceptTouchEvent不执行
            4、ACTION_DOWN -> onInterceptTouchEvent必执行
            5、requestDisallowInterceptTouchEvent -> ViewGroup无法拦截非ACTION_DOWN事件
            */
            if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
                disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    intercepted = onInterceptTouchEvent(ev);
                } else {
                    intercepted = false;
                }
            } else {
                intercepted = true;
            }
            if (!intercepted) {
                final View[] children = mChildren;
                for (int i = childrenCount - 1; i >= 0; i--) {
                    View child = children[childIndex];
                    // 子元素是否在播动画 || 点击事件坐标是否在子元素区域内
                    if (!canViewReceivePointerEvents(child)
                            || !isTransformedTouchPointInView(x, y, child)) {
                        continue;
                    }
                    newTouchTarget = getTouchTarget(child);
                    //  -> child.dispatchTouchEvent
                    if (dispatchTransformedTouchEvent(ev, false, child)) {
                        // 设置mFirstTouchTarget
                        newTouchTarget = addTouchTarget(child);
                        break;
                    }
                }
            }
            /**
            1、ViewGroup没有子元素;
            2、child.dispatchTouchEvent -> false : child.onTouchEvent -> false
            */
            if (mFirstTouchTarget == null) {
                // -> super.dispatchTouchEvent
                handled = dispatchTransformedTouchEvent(ev, canceled, null);
            } 
            return handled;
        }
    
        // View.dispatchTouchEvent()
        public boolean dispatchTouchEvent(MotionEvent event) {
            // mOnToucheListener.onTouch : true -> onTouchEvent不执行
            if (mOnTouchListener != null && mOnTouchListener.onTouch(this, event)) {
                result = true;
            }
            if (!result && onTouchEvent(event)) {
                result = true;
            }
            return result;
        }
        // View.onTouchEvent()
        public boolean onTouchEvent(MotionEvent event) {
            // if(CLICKABLE || LONG_CLICKABLE) : onTouchEvent -> true
            
            if ((viewFlags & ENABLED_MASK) == DISABLED) {
                return (((viewFlags & CLICKABLE) == CLICKABLE
                        || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
            }
            if (((viewFlags & CLICKABLE) == CLICKABLE ||
                    (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
                switch (action) {
                    case MotionEvent.ACTION_UP:
                        performClick();// -> onClick()
                        break;
                }
                return true;
            }
            return false;
        }
        /**
        1、ViewGroup -> dispatchTouchEvent 、onInterceptTouchEvent
        2、View      -> dispatchTouchEvent 、onTouchEvent
        */
        public boolean dispatchTouchEvent(MotionEvent ev) {
            boolean consume = false;
            if(onInterceptTouchEvent(ev)){
                // super.dispatchTouchEvent -> View.dispatchTouchEvent -> onTouchEvent
                consume = onTouchEvent(ev);
            }else{
                // View || ViewGroup -> dispatchTouchEvent
                consume = child.dispatchTouchEvent(ev);
            }
            return consume;
        }
    

    相关文章

      网友评论

          本文标题:Android View事件分发机制

          本文链接:https://www.haomeiwen.com/subject/agufyxtx.html