黄视频网站在线免费观看-黄视频网站在线看-黄视频网站在线观看-黄视频网站免费看-黄视频网站免费观看-黄视频网站免费

千鋒教育-做有情懷、有良心、有品質的職業(yè)教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > ACTION_CANCEL到底何時觸發(fā),滑出子View范圍會發(fā)生什么?

ACTION_CANCEL到底何時觸發(fā),滑出子View范圍會發(fā)生什么?

來源:千鋒教育
發(fā)布人:xqq
時間: 2023-10-12 21:31:42 1697117502

一、ACTION_CANCEL在這些時候會觸發(fā)

1、父view攔截事件

首先要了解ViewGroup什么情況下會攔截事件,請看下面一段代碼:

@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) ...    boolean handled = false;    if (onFilterTouchEventForSecurity(ev))         final int action = ev.getAction();        final int actionMasked = action & MotionEvent.ACTION_MASK;...        // Check for interception.        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;                ...        ...

可以看出有兩個條件:

MotionEvent.ACTION_DOWN事件或者mFirstTouchTarget非空也就是有子view在處理事件子view沒有做攔截,也就是沒有調用ViewParent#requestDisallowInterceptTouchEvent(true)

如果滿足上面的兩個條件才會執(zhí)行onInterceptTouchEvent(ev)。如果ViewGroup攔截了事件,則intercepted變量為true,接著往下看:

@Overridepublic boolean dispatchTouchEvent(MotionEvent ev)         boolean handled = false;    if (onFilterTouchEventForSecurity(ev))         ...        // Check for interception.        final boolean intercepted;        if (actionMasked == MotionEvent.ACTION_DOWN                || mFirstTouchTarget != null)             final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;            if (!disallowIntercept)                 // 當mFirstTouchTarget != null,也就是子view處理了事件                // 此時如果父ViewGroup攔截了事件,intercepted==true                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;                ...        // Dispatch to touch targets.        if (mFirstTouchTarget == null)             ...         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)                     ...                 else                     // 判斷一:此時cancelChild == true                    final boolean cancelChild = resetCancelNextUpFlag(target.child)                            || intercepted;// 判斷二:給child發(fā)送cancel事件                    if (dispatchTransformedTouchEvent(ev, cancelChild,                            target.child, target.pointerIdBits))                         handled = true;                                        ...                ...    return handled;

以上判斷一處cancelChild為true,然后進入判斷二中一看究竟:

private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,            View child, int desiredPointerIdBits)     final boolean handled;    // Canceling motions is a special case.  We don't need to perform any transformations    // or filtering.  The important part is the action, not the contents.    final int oldAction = event.getAction();    if (cancel || oldAction == MotionEvent.ACTION_CANCEL)         // 將event設置成ACTION_CANCEL        event.setAction(MotionEvent.ACTION_CANCEL);        if (child == null)             ...         else             // 分發(fā)給child            handled = child.dispatchTouchEvent(event);                event.setAction(oldAction);        return handled;

當參數(shù)cancel為ture時會將event設置為MotionEvent.ACTION_CANCEL,然后分發(fā)給child。

2、ACTION_DOWN初始化操作

首先請看一段代碼:

public boolean dispatchTouchEvent(MotionEvent ev)     boolean handled = false;    if (onFilterTouchEventForSecurity(ev))         final int action = ev.getAction();        final int actionMasked = action & MotionEvent.ACTION_MASK;        // Handle an initial down.        if (actionMasked == MotionEvent.ACTION_DOWN)             // Throw away all previous state when starting a new touch gesture.            // The framework may have dropped the up or cancel event for the previous gesture            // due to an app switch, ANR, or some other state change.            // 取消并清除所有的Touch目標            cancelAndClearTouchTargets(ev);            resetTouchState();        ...        ...

系統(tǒng)可能會由于App切換、ANR等原因丟失了up,cancel事件。因此需要在ACTION_DOWN時丟棄掉所有前面的狀態(tài),具體代碼如下:

private void cancelAndClearTouchTargets(MotionEvent event)     if (mFirstTouchTarget != null)         boolean syntheticEvent = false;        if (event == null)             final long now = SystemClock.uptimeMillis();            event = MotionEvent.obtain(now, now,                    MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);            syntheticEvent = true;                for (TouchTarget target = mFirstTouchTarget; target != null; target = target.next)             resetCancelNextUpFlag(target.child);            // 分發(fā)事件同情況一            dispatchTransformedTouchEvent(event, true, target.child, target.pointerIdBits);                ...

PS:在dispatchDetachedFromWindow()中也會調用cancelAndClearTouchTargets()

3、在子View處理事件的過程中被從父View中移除時

請看下面這段代碼:

public void removeView(View view)     if (removeViewInternal(view))         requestLayout();        invalidate(true);    private boolean removeViewInternal(View view)     final int index = indexOfChild(view);    if (index >= 0)         removeViewInternal(index, view);        return true;        return false;private void removeViewInternal(int index, View view)     ...    cancelTouchTarget(view);...private void cancelTouchTarget(View view)     TouchTarget predecessor = null;    TouchTarget target = mFirstTouchTarget;    while (target != null)         final TouchTarget next = target.next;        if (target.child == view)             ...            // 創(chuàng)建ACTION_CANCEL事件            MotionEvent event = MotionEvent.obtain(now, now,                    MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);            分發(fā)給目標view            view.dispatchTouchEvent(event);            event.recycle();            return;                predecessor = target;        target = next;

4、子View被設置了PFLAG_CANCEL_NEXT_UP_EVENT標記時

請看下面這段代碼,在情況一種的兩個判斷處:

// 判斷一:此時cancelChild == truefinal boolean cancelChild = resetCancelNextUpFlag(target.child)|| intercepted;// 判斷二:給child發(fā)送cancel事件if (dispatchTransformedTouchEvent(ev, cancelChild,    target.child, target.pointerIdBits))     handled = true;

當?resetCancelNextUpFlag(target.child)?為true時同樣也會導致cancel,查看代碼:

/** * Indicates whether the view is temporarily detached. * * @hide */static final int PFLAG_CANCEL_NEXT_UP_EVENT        = 0x04000000;private static boolean resetCancelNextUpFlag(View view)     if ((view.mPrivateFlags & PFLAG_CANCEL_NEXT_UP_EVENT) != 0)         view.mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;        return true;        return false;

二、滑出子View范圍會發(fā)生什么

通常來說,滑出子View范圍什么也不會發(fā)生。如果手指移出了子View之外,從而導致事件序列被取消,那么通常不會有太多事情發(fā)生。您的應用程序將會收到一個ACTION_CANCEL事件,但是由于事件已經被取消,您無法執(zhí)行任何進一步的操作。如果您希望避免這種情況發(fā)生,您可以嘗試使用requestDisallowInterceptTouchEvent()方法來防止觸摸事件序列被攔截,或者重新設計您的UI以確保用戶不會意外地移動手指到View的范圍外。

延伸閱讀1:ACTION_CANCEL作用

我們知道如果某一個子View處理了Down事件,那么隨之而來的Move和Up事件也會交給它處理。但是交給它處理之前,父View還是可以攔截事件的,如果攔截了事件,那么子View就會收到一個Cancel事件,并且不會收到后續(xù)的Move和Up事件。

聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業(yè)內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
日韩专区一区| 国产麻豆精品免费密入口| 99热精品一区| 久久久成人网| 午夜激情视频在线播放| 夜夜操天天爽| 亚洲精品永久一区| 国产91精品一区| 天天做日日爱夜夜爽| 日韩一级黄色大片| 中文字幕一区二区三区 精品| 精品视频一区二区三区| 可以免费在线看黄的网站| 免费毛片播放| 99色播| 毛片电影网| 国产成人精品综合| 国产91丝袜高跟系列| 欧美激情一区二区三区在线| 久久久久久久免费视频| 精品国产亚洲人成在线| 久久久久久久男人的天堂| 人人干人人插| 国产不卡高清在线观看视频 | 毛片高清| 国产成人欧美一区二区三区的| 台湾毛片| 一 级 黄 中国色 片| 欧美爱色| 欧美18性精品| 午夜家庭影院| 精品在线观看一区| 在线观看成人网 | 麻豆系列 在线视频| 可以免费看污视频的网站| 一级片片| 国产不卡在线观看| 欧美电影免费看大全| 国产伦理精品| 久久国产一区二区| 午夜在线亚洲| 免费国产在线观看不卡| 国产一区二区精品尤物| 免费一级生活片| 台湾毛片| 青青久久精品| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 黄视频网站免费| 日韩综合| 国产福利免费观看| 国产视频在线免费观看| 国产精品1024永久免费视频| 国产不卡高清| 国产高清视频免费| 九九精品影院| 午夜欧美成人久久久久久| 免费国产在线观看不卡| 日日爽天天| 成人免费一级毛片在线播放视频| 成人a大片在线观看| 欧美一级视频免费| 欧美激情一区二区三区在线播放 | 日韩一级黄色大片| 欧美国产日韩在线| 欧美日本二区| 精品毛片视频| 九九精品影院| 欧美一级视| 欧美另类videosbestsex高清 | 91麻豆爱豆果冻天美星空| 久久精品人人做人人爽97| 久久精品免视看国产明星| 国产亚洲精品aaa大片| 精品视频在线观看一区二区三区| 精品毛片视频| 精品国产香蕉在线播出| 久久国产影院| 日本特黄特色aaa大片免费| 亚洲精品中文字幕久久久久久| 免费毛片播放| 午夜欧美成人久久久久久| 国产一区二区精品尤物| 国产不卡在线看| 九九久久99综合一区二区| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 免费国产一级特黄aa大片在线| 香蕉视频亚洲一级| 四虎影视久久| 天天色成人网| 日本伦理网站| 成人免费福利片在线观看| 国产精品免费精品自在线观看| 久久精品成人一区二区三区| 毛片高清| 国产精品1024永久免费视频| 日韩在线观看视频黄| 亚洲第一色在线| 韩国三级视频网站| 日本在线www| 久久国产精品只做精品| 高清一级片| 精品国产一区二区三区久久久狼| 日韩免费在线| 国产不卡高清| a级毛片免费观看网站| 精品视频在线看 | 欧美爱爱网| 九九干| 成人高清视频免费观看| 一级毛片视频播放| 国产极品精频在线观看| 国产一区二区精品在线观看| 亚洲精品中文字幕久久久久久| a级毛片免费全部播放| 色综合久久手机在线| 国产a视频精品免费观看| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 亚洲爆爽| 尤物视频网站在线观看| 国产综合91天堂亚洲国产| 日韩中文字幕在线播放| 国产不卡在线观看| 国产91精品一区| 欧美电影免费| 国产一区国产二区国产三区| 沈樵在线观看福利| 国产伦久视频免费观看视频| 美女免费毛片| 国产麻豆精品高清在线播放| 日日日夜夜操| 高清一级淫片a级中文字幕| 精品久久久久久综合网| 国产不卡福利| 四虎久久影院| 日本免费乱理伦片在线观看2018| 欧美激情一区二区三区视频高清 | 午夜在线亚洲| 香蕉视频久久| 一级女性全黄久久生活片| 国产视频在线免费观看| 中文字幕97| 一级毛片视频免费| 亚欧视频在线| 日韩专区在线播放| 天天做日日爱| 精品视频在线观看一区二区| 精品国产一区二区三区国产馆| 日韩在线观看视频免费| 欧美另类videosbestsex高清| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 国产不卡精品一区二区三区| 青青青草视频在线观看| 99久久精品国产高清一区二区| a级毛片免费全部播放| 日日夜夜婷婷| 国产精品自拍在线| 国产精品免费精品自在线观看| 精品久久久久久中文字幕2017| 国产网站免费| 青青久在线视频| 九九久久国产精品大片| 国产一区二区精品尤物| 国产网站免费视频| 国产综合91天堂亚洲国产| 成人高清护士在线播放| 国产精品自拍亚洲| 国产91精品一区二区| 久久久久久久久综合影视网| 日韩免费在线| 欧美另类videosbestsex高清| 国产成人精品综合在线| 日韩综合| 日本在线播放一区| 国产视频一区二区在线播放| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 91麻豆精品国产自产在线| 欧美大片一区| 可以免费看污视频的网站| 精品国产香蕉在线播出| 日韩欧美一及在线播放| 国产精品1024在线永久免费| 一级毛片视频播放| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 91麻豆精品国产自产在线观看一区| 成人免费观看男女羞羞视频| 日韩欧美一二三区| 美国一区二区三区| 日日夜夜婷婷| 可以免费在线看黄的网站| 国产伦久视频免费观看视频| 日本免费区| 麻豆午夜视频| 一级女人毛片人一女人| 国产91精品系列在线观看| 天天做日日爱| 日本特黄特黄aaaaa大片| 青青久久网| 韩国三级香港三级日本三级| 久久久成人网| 精品国产三级a|