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

資訊專欄INFORMATION COLUMN

View源碼-Touch事件

Barry_Ng / 1184人閱讀

摘要:接下來(lái)查看方法的源碼里面的處理如下如果則返回,即該對(duì)觸摸事件不予處理。顯示了提示框的話則隱藏如果不可點(diǎn)擊,則移除長(zhǎng)按事件的檢測(cè),返回否則繼續(xù)向下走。當(dāng)前是點(diǎn)擊事件,所以移除長(zhǎng)按事件的檢測(cè)。關(guān)于源碼中的事件,可以參考文章源碼事件

在Android-27中查看源碼:

首先我們來(lái)查看單個(gè)View的觸摸事件的處理,在View的dispatchTouchEvent方法中看看源碼是如何處理的。

public boolean dispatchTouchEvent(MotionEvent event) {
        // If the event should be handled by accessibility focus first.
        if (event.isTargetAccessibilityFocus()) {
            // We don"t have focus or no virtual descendant has it, do not handle the event.
            if (!isAccessibilityFocusedViewOrHost()) {
                return false;
            }
            // We have focus and got the event, then use normal event dispatch.
            event.setTargetAccessibilityFocus(false);
        }

        boolean result = false;

        if (mInputEventConsistencyVerifier != null) {
            mInputEventConsistencyVerifier.onTouchEvent(event, 0);
        }

        final int actionMasked = event.getActionMasked();
        if (actionMasked == MotionEvent.ACTION_DOWN) {
            // Defensive cleanup for new gesture
            stopNestedScroll();
        }

        if (onFilterTouchEventForSecurity(event)) {
            if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
                result = true;
            }
            //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;
            }
        }

        if (!result && mInputEventConsistencyVerifier != null) {
            mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
        }

        // Clean up after nested scrolls if this is the end of a gesture;
        // also cancel it if we tried an ACTION_DOWN but we didn"t want the rest
        // of the gesture.
        if (actionMasked == MotionEvent.ACTION_UP ||
                actionMasked == MotionEvent.ACTION_CANCEL ||
                (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
            stopNestedScroll();
        }

        return result;
    }

dispatchTouchEvent處理過(guò)程如下:

如果設(shè)置了OnTouchListener和enabled為true,并且onTouch返回為true,即該View在OnTouchListener的onTouch方法中處理了觸摸事件。

如果onTouchEvent返回為true,即該View在onTouchEvent中處理了觸摸事件。

如果觸摸事件在該View中得到處理則返回true,否則返回false(即該View對(duì)觸摸事件不予處理)。

接下來(lái)查看onTouchEvent方法的源碼:

    public boolean onTouchEvent(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();
        final int viewFlags = mViewFlags;
        final int action = event.getAction();

        final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE
                || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
                || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;

        if ((viewFlags & ENABLED_MASK) == DISABLED) {
            if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
                setPressed(false);
            }
            mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
            // A disabled view that is clickable still consumes the touch
            // events, it just doesn"t respond to them.
            return clickable;
        }
        if (mTouchDelegate != null) {
            if (mTouchDelegate.onTouchEvent(event)) {
                return true;
            }
        }

        if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
            switch (action) {
                case MotionEvent.ACTION_UP:
                    mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
                    if ((viewFlags & TOOLTIP) == TOOLTIP) {
                        handleTooltipUp();
                    }
                    if (!clickable) {
                        removeTapCallback();
                        removeLongPressCallback();
                        mInContextButtonPress = false;
                        mHasPerformedLongPress = false;
                        mIgnoreNextUpEvent = false;
                        break;
                    }
                    boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
                    if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
                        // take focus if we don"t have it already and we should in
                        // touch mode.
                        boolean focusTaken = false;
                        if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
                            focusTaken = requestFocus();
                        }

                        if (prepressed) {
                            // The button is being released before we actually
                            // showed it as pressed.  Make it show the pressed
                            // state now (before scheduling the click) to ensure
                            // the user sees it.
                            setPressed(true, x, y);
                        }

                        if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
                            // This is a tap, so remove the longpress check
                            removeLongPressCallback();

                            // Only perform take click actions if we were in the pressed state
                            if (!focusTaken) {
                                // Use a Runnable and post this rather than calling
                                // performClick directly. This lets other visual state
                                // of the view update before click actions start.
                                if (mPerformClick == null) {
                                    mPerformClick = new PerformClick();
                                }
                                if (!post(mPerformClick)) {
                                    performClick();
                                }
                            }
                        }

                        if (mUnsetPressedState == null) {
                            mUnsetPressedState = new UnsetPressedState();
                        }

                        if (prepressed) {
                            postDelayed(mUnsetPressedState,
                                    ViewConfiguration.getPressedStateDuration());
                        } else if (!post(mUnsetPressedState)) {
                            // If the post failed, unpress right now
                            mUnsetPressedState.run();
                        }

                        removeTapCallback();
                    }
                    mIgnoreNextUpEvent = false;
                    break;

                case MotionEvent.ACTION_DOWN:
                    if (event.getSource() == InputDevice.SOURCE_TOUCHSCREEN) {
                        mPrivateFlags3 |= PFLAG3_FINGER_DOWN;
                    }
                    mHasPerformedLongPress = false;

                    if (!clickable) {
                        checkForLongClick(0, x, y);
                        break;
                    }

                    if (performButtonActionOnTouchDown(event)) {
                        break;
                    }

                    // Walk up the hierarchy to determine if we"re inside a scrolling container.
                    boolean isInScrollingContainer = isInScrollingContainer();

                    // For views inside a scrolling container, delay the pressed feedback for
                    // a short period in case this is a scroll.
                    if (isInScrollingContainer) {
                        mPrivateFlags |= PFLAG_PREPRESSED;
                        if (mPendingCheckForTap == null) {
                            mPendingCheckForTap = new CheckForTap();
                        }
                        mPendingCheckForTap.x = event.getX();
                        mPendingCheckForTap.y = event.getY();
                        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                    } else {
                        // Not inside a scrolling container, so show the feedback right away
                        setPressed(true, x, y);
                        checkForLongClick(0, x, y);
                    }
                    break;

                case MotionEvent.ACTION_CANCEL:
                    if (clickable) {
                        setPressed(false);
                    }
                    removeTapCallback();
                    removeLongPressCallback();
                    mInContextButtonPress = false;
                    mHasPerformedLongPress = false;
                    mIgnoreNextUpEvent = false;
                    mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
                    break;

                case MotionEvent.ACTION_MOVE:
                    if (clickable) {
                        drawableHotspotChanged(x, y);
                    }

                    // Be lenient about moving outside of buttons
                    if (!pointInView(x, y, mTouchSlop)) {
                        // Outside button
                        // Remove any future long press/tap checks
                        removeTapCallback();
                        removeLongPressCallback();
                        if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
                            setPressed(false);
                        }
                        mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
                    }
                    break;
            }

            return true;
        }

        return false;
    }

onTouchEvent里面的處理如下:

如果setEnabled(false),則返回false,即該View對(duì)觸摸事件不予處理。

如果設(shè)置了TouchDelegate,并且TouchDelegate的onTouchEvent返回true,則返回true,即由TouchDelegate中的onTouchEvent方法處理了觸摸事件。否則繼續(xù)向下。

如果該View不可點(diǎn)擊并且(viewFlags & TOOLTIP) != TOOLTIP(即當(dāng)停留或長(zhǎng)按在該view時(shí)不可顯示提示框),則返回false,即該View對(duì)觸摸事件不予處理。否則繼續(xù)向下。

根據(jù)觸摸事件的分類進(jìn)行處理:

MotionEvent.ACTION_DOWN:

不可點(diǎn)擊或者不在可滑動(dòng)的容器內(nèi):如果LONG_CLICKABLE為true則執(zhí)行OnLongClickListener的onLongClick方法;或者設(shè)置了viewFlags為TOOLTIP,則執(zhí)行showTooltip(顯示提示框)。然后返回true,即該View處理了觸摸事件,否則繼續(xù)向下走。

MotionEvent.ACTION_MOVE:在手指移動(dòng)的過(guò)程中判斷是否仍在當(dāng)前view的范圍。

MotionEvent.ACTION_UP:

顯示了提示框的話則隱藏;

如果不可點(diǎn)擊,則移除長(zhǎng)按事件的檢測(cè),返回true,否則繼續(xù)向下走。

當(dāng)前是點(diǎn)擊事件,所以移除長(zhǎng)按事件的檢測(cè)。然后執(zhí)行performClick方法,返回true,即該View處理了觸摸事件。

關(guān)于ViewGroup源碼中的Touch事件,可以參考文章:ViewGroup源碼-Touch事件

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/72174.html

相關(guān)文章

  • ViewGroup源碼-Touch事件

    摘要:在中查看源碼在看完源碼的觸摸事件源碼事件后,我們接著來(lái)看看容器類的觸摸事件。同樣的先來(lái)看源碼中的方法首先,會(huì)判斷是否不允許攔截,可以通過(guò)進(jìn)行設(shè)置,默認(rèn)允許攔截。 在Android-27中查看源碼: 在看完View源碼的觸摸事件(View源碼-Touch事件)后,我們接著來(lái)看看容器類View的觸摸事件。因?yàn)槿萜黝惖腣iew都繼承自ViewGroup,所以我們?cè)赩iewGroup的源碼中來(lái)...

    rozbo 評(píng)論0 收藏0
  • View事件機(jī)制分析

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

    bergwhite 評(píng)論0 收藏0
  • View事件機(jī)制源碼分析

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

    antz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<