摘要:接下來(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
摘要:在中查看源碼在看完源碼的觸摸事件源碼事件后,我們接著來(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)...
摘要:注意,事件分發(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...
摘要:當(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...
閱讀 1309·2021-11-15 11:37
閱讀 2564·2021-09-22 10:56
閱讀 3391·2021-09-06 15:11
閱讀 801·2021-08-31 09:45
閱讀 2897·2021-07-28 11:16
閱讀 1806·2019-08-30 15:44
閱讀 477·2019-08-30 13:22
閱讀 3344·2019-08-30 13:18