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

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的事件分发机制(三))