国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ViewGroup源碼-Touch事件

rozbo / 3298人閱讀

摘要:在中查看源碼在看完源碼的觸摸事件源碼事件后,我們接著來看看容器類的觸摸事件。同樣的先來看源碼中的方法首先,會判斷是否不允許攔截,可以通過進行設(shè)置,默認(rèn)允許攔截。

在Android-27中查看源碼:

在看完View源碼的觸摸事件(View源碼-Touch事件)后,我們接著來看看容器類View的觸摸事件。因為容器類的View都繼承自ViewGroup,所以我們在ViewGroup的源碼中來看看是如何處理觸摸事件的。

同樣的先來看ViewGroup源碼中的dispatchTouchEvent方法:

final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
    final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
    if (!disallowIntercept) {
        intercepted = onInterceptTouchEvent(ev);
        ev.setAction(action); // restore action in case it was changed
    } else {
        intercepted = false;
    }
} else {
    // There are no touch targets and this action is not an initial down
    // so this view group continues to intercept touches.
    intercepted = true;
}

首先,會判斷是否不允許攔截,可以通過requestDisallowInterceptTouchEvent進行設(shè)置,默認(rèn)允許攔截。如果允許攔截,會調(diào)用onInterceptTouchEvent,看看該View是否攔截了觸摸事件,默認(rèn)不攔截即可以將觸摸事件向子View傳遞。

接下來,如果觸摸事件沒有取消并且沒有攔截,在手指按下的時候:

final ArrayList preorderedList = buildTouchDispatchChildList();
...
for (int i = childrenCount - 1; i >= 0; i--){
    ...
    newTouchTarget = getTouchTarget(child);
    if (newTouchTarget != null) {
        // Child is already receiving touch within its bounds.
        // Give it the new pointer in addition to the ones it is handling.
        newTouchTarget.pointerIdBits |= idBitsToAssign;
        break;
    }
    resetCancelNextUpFlag(child);
    if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
        // Child wants to receive touch within its bounds.
        mLastTouchDownTime = ev.getDownTime();
        if (preorderedList != null) {
            // childIndex points into presorted list, find original index
            for (int j = 0; j < childrenCount; j++) {
                if (children[childIndex] == mChildren[j]) {
                    mLastTouchDownIndex = j;
                    break;
                }
            }
        } else {
            mLastTouchDownIndex = childIndex;
        }
        mLastTouchDownX = ev.getX();
        mLastTouchDownY = ev.getY();
        newTouchTarget = addTouchTarget(child, idBitsToAssign);
        alreadyDispatchedToNewTouchTarget = true;
        break;
    }
...
}

按照繪制子View的順序,找到該ViewGoup的所有子view,并保存到ArrayList中。

根據(jù)視圖順序依次遍歷子View。判斷當(dāng)前子view是否是TouchTarget,若是則跳出循環(huán)。否則調(diào)用dispatchTransformedTouchEvent方法,如果當(dāng)前子View的dispatchTouchEvent返回為true,找到該子View在ViewGroup中的index,并將該子View作為新的TouchTarget。

清楚保存了所有子View的ArrayList。

然后在TouchTarget形成的鏈?zhǔn)浇Y(jié)構(gòu)中,處理觸摸事件:

// Dispatch to touch targets.
if (mFirstTouchTarget == null) {
    // No touch targets so treat this as an ordinary view.
    handled = dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);
} else {
    // Dispatch to touch targets, excluding the new touch target if we already
    // dispatched to it.  Cancel touch targets if necessary.
    TouchTarget predecessor = null;
    TouchTarget target = mFirstTouchTarget;
    while (target != null) {
        final TouchTarget next = target.next;
        if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
            handled = true;
        } else {
            final boolean cancelChild = resetCancelNextUpFlag(target.child) || intercepted;
            if (dispatchTransformedTouchEvent(ev, cancelChild,target.child, target.pointerIdBits)) {
                handled = true;
            }
            if (cancelChild) {
                if (predecessor == null) {
                    mFirstTouchTarget = next;
                } else {
                    predecessor.next = next;
                }
                target.recycle();
                target = next;
                continue;
            }
        }
        predecessor = target;
        target = next;
    }
}

如果子View沒有處理觸摸事件,則由當(dāng)前的ViewGroup處理,然后返回處理結(jié)果。因為ViewGroup是View的子類,所以還是由View的dispatchTouchEvent處理。

如果子View中處理了觸摸事件,根據(jù)TouchTarget生成的鏈?zhǔn)浇Y(jié)構(gòu),不斷循環(huán),分別調(diào)用里面View的dispatchTouchEvent方法。

從上面的分析可以看出整個ViewGroup的Touch事件的整個傳遞過程如下:

是否調(diào)用了requestDisallowInterceptTouchEvent方法設(shè)置不允許攔截,默認(rèn)允許攔截。若允許攔截,則再調(diào)用onInterceptTouchEvent,看是否攔截。

如果觸摸事件被攔截,則調(diào)用ViewGroup的dispatchTransformedTouchEvent方法,其實是調(diào)用View的dispatchTouchEvent方法。否則繼續(xù)向下。

當(dāng)觸摸事件為MotionEvent.ACTION_DOWN時,首先獲取根據(jù)繪制順序保存了所有子View的ArrayLsit,然后再根據(jù)視圖順序去遍歷子View。

如果從TouchTarget形成的鏈表中發(fā)現(xiàn)該View,則跳出循環(huán),即找到了TouchTarget。否則繼續(xù)向下。

在子View中尋找,當(dāng)子View的dispatchTouchEvent方法返回為true時,則找到了新的TouchTarget,并將其添加到TouchTarget形成的鏈表中。

遍歷TouchTarget形成的鏈表,然后對鏈表里面的子View分別調(diào)用dispatchTouchEvent,最后將處理結(jié)果返回。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/72185.html

相關(guān)文章

  • View事件機制分析

    摘要:注意,事件分發(fā)是向下傳遞的,也就是父到子的順序。事件分發(fā)機制的本質(zhì)是要解決,點擊事件由哪個對象發(fā)出,經(jīng)過哪些對象,最終達到哪個對象并最終得到處理。表示以及分發(fā)給其中在內(nèi)部完成被賦值。會自己處理事件。 目錄介紹 01.Android中事件分發(fā)順序 1.1 事件分發(fā)的對象是誰 1.2 事件分發(fā)的本質(zhì) 1.3 事件在哪些對象間進行傳遞 1.4 事件分發(fā)過程涉及方法 1.5 Androi...

    bergwhite 評論0 收藏0
  • View事件機制源碼分析

    摘要:當(dāng)不攔截事件的時候,事件會向下分發(fā)交由它的子或進行處理。表示以及分發(fā)給其中在內(nèi)部完成被賦值。會自己處理事件。 目錄介紹 01.Android中事件分發(fā)順序 02.Activity的事件分發(fā)機制 2.1 源碼分析 2.2 點擊事件調(diào)用順序 2.3 得出結(jié)論 03.ViewGroup事件的分發(fā)機制 3.1 看一下這個案例 3.2 源碼分析 3.3 得出結(jié)論 04.Vie...

    antz 評論0 收藏0
  • View源碼-Touch事件

    摘要:接下來查看方法的源碼里面的處理如下如果則返回,即該對觸摸事件不予處理。顯示了提示框的話則隱藏如果不可點擊,則移除長按事件的檢測,返回否則繼續(xù)向下走。當(dāng)前是點擊事件,所以移除長按事件的檢測。關(guān)于源碼中的事件,可以參考文章源碼事件 在Android-27中查看源碼: 首先我們來查看單個View的觸摸事件的處理,在View的dispatchTouchEvent方法中看看源碼是如何處理的。 p...

    Barry_Ng 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<