美文网首页
3.4 View的事件分发机制(三)

3.4 View的事件分发机制(三)

作者: 武安长空 | 来源:发表于2016-06-21 11:09 被阅读24次

    View的点击事件伪代码:

    public boolean dispatchTouchEvent(MotionEvent ev) {
        // 判断当前事件到来前,窗口有没有被遮罩,如果有则返回false,没有则返回true
        if (onFilterTouchEventForSecurity(event)) {
            // 判断onTouchListener
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }
            // 调用onTouchEvent方法 
            if (!result && onTouchEvent(event)) {
                result = true;
            }
        }
    
    }
    
    // 调子View分发的方法
    static class ListenerInfo {
        public OnClickListener mOnClickListener;
        // ...
        private OnTouchListener mOnTouchListener;
    }
    
    
    public boolean onTouchEvent(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();
        final int viewFlags = mViewFlags;
        final int action = event.getAction();
    
        if ((viewFlags & ENABLED_MASK) == DISABLED) {
            // 不可点击.即使是不可点击,如果它自身是可点击或者可长按的话,一样会消耗事件(return true),只是不作出任何反应(不会执行下面的代码)。
            return (((viewFlags & CLICKABLE) == CLICKABLE
                    || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
                    || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE);
        }
    
        if (mTouchDelegate != null) {
            if (mTouchDelegate.onTouchEvent(event)) {
                return true;
            }
        }
    
        if (((viewFlags & CLICKABLE) == CLICKABLE ||
                (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||
                (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {
            // clickable或者long_clickable或者context_clickable有一个为true则return true
            switch (action) {
                case MotionEvent.ACTION_UP:
                    handleActionUp(action);
                    break;
                case MotionEvent.ACTION_DOWN:
                    // ...
                    break;
                case MotionEvent.ACTION_CANCEL:
                    // ...
                    break;
                case MotionEvent.ACTION_MOVE:
                    // ...
                    break;
            }
            return true;
        }
        // clickable或者long_clickable或者context_clickable全为false则return false
        return false;
    }
    
    // up的时候处理点击事件
    public void handleActionUp(MotionEvent action){
        if (mPerformClick == null) {
            mPerformClick = new PerformClick();
        }
        if (!post(mPerformClick)) {
            performClick();
        }
    }
    // clickListener
    public boolean performClick() {
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }
    
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        return result;
    }
    

    相关文章

      网友评论

          本文标题:3.4 View的事件分发机制(三)

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