View事件分發(fā)總結(jié)

1.事件分發(fā)核心方法

  1. dispatchTouchEvent (事件分發(fā),activity,ViewGroup,View 擁有)
  • 返回true表示事件分發(fā)成功,事件消費(fèi)
  • 返回false表示分發(fā)事件失敗,事件傳遞到上層View的onTouchEvent
  • 默認(rèn)調(diào)用super.dispatchTouchEvent ,分發(fā)事件,執(zhí)行分發(fā)流程,
  1. onInterceptTouchEvent(事件攔截,ViewGroup擁有)
  • 返回true,表示進(jìn)行攔截,不會(huì)進(jìn)行事件分發(fā)到子View,有viewgroup調(diào)用自己的onTouchEvent方法進(jìn)行處理。
  • 返回false,不進(jìn)行攔截,執(zhí)行既定的分發(fā)過(guò)程
  • ViewGroup默認(rèn)不攔截事件
  1. onTouchEvent(事件消耗,activity,ViewGroup,View 擁有)
  • 執(zhí)行到該方法說(shuō)明該View/ViewGroup在觸摸返回內(nèi)
  • 返回true,表示觸摸事件被該view消費(fèi)掉
  • 返回false,表示觸摸事件該View沒(méi)有消費(fèi)掉,則依次回溯到上層傳遞的

2. 事件分發(fā)流程

  • 分發(fā)流程:Activity======>ViewGroup(觸摸區(qū)域內(nèi))====>View(觸摸區(qū)域內(nèi))
  • 消費(fèi)流程:View(onTouchEvent 返回false)======>ViewGroup(onTouchEvent 返回false)=====>Activity

2.1分發(fā)流程結(jié)論

  • ACTION_DOWN 事件會(huì)一直分發(fā)到最底層的View并交由它的onTouchEvent方法處理,返回false,表示它不處理該事件序列,后續(xù)的move,up,等事件將不會(huì)向他分發(fā)。同理與這個(gè)事件序列的所有View,當(dāng)所有View都沒(méi)有消費(fèi)這個(gè)事件則最后調(diào)用activity的onTouchEvent方法,后續(xù)的move,up事件直接由activity的 dispatchTouchEvent (activity) ======>onTouchEvent(activ)
  • 事件攔截onInterceptTouchEvent,可以攔截所有事件,也可以攔截部分事件,down-move-up,子View可以調(diào)用父View的requestDisallowInterceptTouchEvent,不允許父View攔截,但如果父View攔截了Down事件,這個(gè)方法是無(wú)效的。
  • view什么時(shí)候會(huì)消耗事件,即onTouchEvent返回true,clickAble或longclickable有一個(gè)為真,具體表示就是添加相關(guān)的監(jiān)聽(tīng)事件,表示我們有相關(guān)業(yè)務(wù)需要處理。mOnTouchListener的ontouch事件要優(yōu)先于onTouchEvent事件,當(dāng)返回true時(shí),表示事件已經(jīng)被消費(fèi),不會(huì)再進(jìn)行分發(fā)。
    view的dispatchTouchEvent 部分源碼
//noinspection SimplifiableIfStatement
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            if (!result && onTouchEvent(event)) {
                result = true;
            }

setOnTouchListener

   /**
     * Register a callback to be invoked when a touch event is sent to this view.
     * @param l the touch listener to attach to this view
     */
    public void setOnTouchListener(OnTouchListener l) {
        getListenerInfo().mOnTouchListener = l;
    }

setOnClickListener

    /**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(@Nullable OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }

setOnLongClickListener

/**
     * Register a callback to be invoked when this view is clicked and held. If this view is not
     * long clickable, it becomes long clickable.
     *
     * @param l The callback that will run
     *
     * @see #setLongClickable(boolean)
     */
    public void setOnLongClickListener(@Nullable OnLongClickListener l) {
        if (!isLongClickable()) {
            setLongClickable(true);
        }
        getListenerInfo().mOnLongClickListener = l;
    }

3.事件序列

一個(gè)事件序列包含ACTION_DOWN(1次) -> ACTION_MOVE(N次) -> ACTION_UP(1次),事件分發(fā)包含一個(gè)完整的事件序列(從屏幕的的觸摸到離開(kāi)的過(guò)程)。


view事件分發(fā)規(guī)則說(shuō)明圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容