在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    Framework事件機制-深扒onInterceptTouchEvent攔截流程解析

    Framework事件機制-深扒onInterceptTouchEvent攔截流程解析

    一、基本知識

    1.事件分發(fā)的三個函數(shù)

    事件的分發(fā) dispatchTouchEvent()

    事件的攔截 onInterceptTouchEvent()

    事件的處理(消費) onTouchEvent()

    2.事件分發(fā)的對象

    被分發(fā)的對象是那些?被分發(fā)的對象是用戶觸摸屏幕而產(chǎn)生的點擊事件,事件主要包括:按下、滑動、抬起與取消。這些事件被封裝成MotionEvent對象。

    MotionEvent.ACTION_DOWN 在屏幕按下時 MotionEvent.ACTION_MOVE 在屏幕上滑動時 MotionEvent.ACTION_UP 在屏幕抬起時 MotionEvent.ACTION_CANCLE 滑動超出控件邊界時

    3.分發(fā)事件的組件

    分發(fā)事件的組件,也稱為分發(fā)事件者,包括Activity、View和ViewGroup。它們?nèi)叩囊话憬Y(jié)構(gòu)為:

    二、事件處理流程

    首先,我們需要了解事件處理中的幾個方法

    1、在ViewGroup中,事件分為dispatchTouchEvent(事件的分發(fā)),onInterceptTouchEvent(事件的攔截),onTouchEvent(事件的處理)。

    2、在View中,事件分為dispatchTouchEvent(事件的分發(fā)),onTouchEvent(事件的處理)。

    下面是demo的界面結(jié)構(gòu),它是由兩個自定義的ViewGroup和一個自定義的View組成,并分別重寫了它們的以上幾個方法。

    其中MyViewGroupA代碼如下:

    public class MyViewGroupA extends LinearLayout { public MyViewGroupA(Context context) { super(context); } public MyViewGroupA(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyViewGroupA”,”dispatchTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyViewGroupA”,”dispatchTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyViewGroupA”,”dispatchTouchEvent_ACTION_UP”); break; } return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyViewGroupA”,”onInterceptTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyViewGroupA”,”onInterceptTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyViewGroupA”,”onInterceptTouchEvent_ACTION_UP”); break; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyViewGroupA”,”onTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyViewGroupA”,”onTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyViewGroupA”,”onTouchEvent_ACTION_UP”); break; } return super.onTouchEvent(event); }}

    MyViewGroupB代碼如下:

    public class MyViewGroupB extends LinearLayout { public MyViewGroupB(Context context) { super(context); } public MyViewGroupB(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyViewGroupB”,”dispatchTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyViewGroupB”,”dispatchTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyViewGroupB”,”dispatchTouchEvent_ACTION_UP”); break; } return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyViewGroupB”,”onInterceptTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyViewGroupB”,”onInterceptTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyViewGroupB”,”onInterceptTouchEvent_ACTION_UP”); break; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyViewGroupB”,”onTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyViewGroupB”,”onTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyViewGroupB”,”onTouchEvent_ACTION_UP”); break; } return super.onTouchEvent(event); }}

    MyView代碼如下:

    public class MyView extends View { public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyView”,”dispatchTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyView”,”dispatchTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyView”,”dispatchTouchEvent_ACTION_UP”); break; } return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“MyView”,”onTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“MyView”,”onTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“MyView”,”onTouchEvent_ACTION_UP”); break; } return super.onTouchEvent(event); }}

    我們說過,事件傳遞是由上到下的,所以最外層的View首先對事件進行操作。而我們最外層是Activity,所以事件也是從這里開始。 Activity代碼如下:

    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“Activity”,”dispatchTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“Activity”,”dispatchTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“Activity”,”dispatchTouchEvent_ACTION_UP”); break; } return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.i(“Activity”,”onTouchEvent_ACTION_DOWN”); break; case MotionEvent.ACTION_MOVE: Log.i(“Activity”,”onTouchEvent_ACTION_MOVE”); break; case MotionEvent.ACTION_UP: Log.i(“Activity”,”onTouchEvent_ACTION_UP”); break; } return super.onTouchEvent(event); }}

    現(xiàn)在我們通過觸摸MyView開始進行分析。雖然dispatchTouchEvent是事件開始的第一步,但是在開發(fā)中,我們通常很少改寫它,所以我們下面只討論其他兩個方法。 1、對以上方法均不作處理,都返回super。這意味著我們既不攔截,也不消費。

    大家看輸出結(jié)果:

    I/Activity: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: onInterceptTouchEvent_ACTION_DOWNI/MyViewGroupB: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupB: onInterceptTouchEvent_ACTION_DOWNI/MyView: dispatchTouchEvent_ACTION_DOWNI/MyView: onTouchEvent_ACTION_DOWNI/MyViewGroupB: onTouchEvent_ACTION_DOWNI/MyViewGroupA: onTouchEvent_ACTION_DOWNI/Activity: onTouchEvent_ACTION_DOWNI/Activity: dispatchTouchEvent_ACTION_MOVEI/Activity: onTouchEvent_ACTION_MOVEI/Activity: dispatchTouchEvent_ACTION_UPI/Activity: onTouchEvent_ACTION_UP

    結(jié)合輸出結(jié)果,我們可以總結(jié)出以下的結(jié)論:

    結(jié)合流程圖,不難發(fā)現(xiàn),如果我對事件既不攔截,也不消費,當觸發(fā)ACTION_DOWN的時候,事件會經(jīng)過Activity——MyViewGroupA——MyViewGroupB——MyView一層層的向下進行dispatchTouchEvent(分發(fā))—onInterceptTouchEvent(攔截)調(diào)用。當?shù)竭_最底層MyView后,開始觸發(fā)消費操作,因為我均不消費,ACTION_DOWN將由底層一層層向上冒,移交上層處理。當?shù)诌_最上層Activity后,說明下層均不消費,之后觸發(fā)的ACTION_MOVE和ACTION_UP將不再向下層分發(fā)傳遞,直接交由Activity分發(fā)給自己進行處理。

    2、我們將MyVIewGroupB的onInterceptTouchEvent返回值改為true,其他均是super。這意味著僅僅MyViewGroupB進行事件攔截,但均無消費

    輸出結(jié)果如下:

    I/Activity: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: onInterceptTouchEvent_ACTION_DOWNI/MyViewGroupB: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupB: onInterceptTouchEvent_ACTION_DOWNI/MyViewGroupB: onTouchEvent_ACTION_DOWNI/MyViewGroupA: onTouchEvent_ACTION_DOWNI/Activity: onTouchEvent_ACTION_DOWNI/Activity: dispatchTouchEvent_ACTION_MOVEI/Activity: onTouchEvent_ACTION_MOVEI/Activity: dispatchTouchEvent_ACTION_UPI/Activity: onTouchEvent_ACTION_UP

    結(jié)合輸出結(jié)果,總結(jié)如下:

    當觸發(fā)ACTION_DOWN的時候,事件依然是從Activity開始一層層向下傳遞,當傳遞到MyViewGroupB時,因為進行了事件攔截,所以執(zhí)行完onInterceptTouchEvent后不再向下傳遞,而是直接交由MyViewGroupB的onTouchEvent進行消費處理。由于我們是只攔截,不消費,所以事件向上傳遞,交由上層處理,最終回到Activity。之后觸發(fā)的ACTION_MOVE和ACTION_UP也不再向下傳遞,直接交由Activity分發(fā)給自己處理。

    3、我們還是將MyViewGroupB的onInterceptTouchEvent返回super,但是將他的onTouchEvent返回true。這意味著我們不攔截,但是由MyViewGroupB進行事件處理。

    輸出結(jié)果如下:

    I/Activity: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: onInterceptTouchEvent_ACTION_DOWNI/MyViewGroupB: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupB: onInterceptTouchEvent_ACTION_DOWNI/MyView: dispatchTouchEvent_ACTION_DOWNI/MyView: onTouchEvent_ACTION_DOWNI/MyViewGroupB: onTouchEvent_ACTION_DOWNI/Activity: dispatchTouchEvent_ACTION_MOVEI/MyViewGroupA: dispatchTouchEvent_ACTION_MOVEI/MyViewGroupA: onInterceptTouchEvent_ACTION_MOVEI/MyViewGroupB: dispatchTouchEvent_ACTION_MOVEI/MyViewGroupB: onTouchEvent_ACTION_MOVEI/Activity: dispatchTouchEvent_ACTION_UPI/MyViewGroupA: dispatchTouchEvent_ACTION_UPI/MyViewGroupA: onInterceptTouchEvent_ACTION_UPI/MyViewGroupB: dispatchTouchEvent_ACTION_UPI/MyViewGroupB: onTouchEvent_ACTION_UP

    結(jié)合輸出結(jié)果,總結(jié)如下:

    可以看出,當觸發(fā)ACTION_DOWN的時候,事件的分發(fā)傳遞過程和1的時候一樣,從Activity開始一層層向下傳遞,最終傳遞到最底層MyView,觸發(fā)消費操作,然后MyView將消費操作移交上層處理,然后到達MyViewGroupB的onTouchEvent,并且進行了消費處理,事件處理到此不在向上移交。當觸發(fā)ACTION_MOVE和ACTION_UP操作時,事件依然需要由Activity開始向下分發(fā)傳遞,但是當傳遞到MyViewGroupB后,由于其消費了ACTION_DOWN,事件將不再繼續(xù)向下分發(fā),而是直接由MyViewGroupB分發(fā)給自己的onTouchEvent進行繼續(xù)處理。事件處理也不再向上移交。

    4、將MyViewGroupB的onInterceptTouchEvent和onTouchEvent的返回值均改為true。這意味著既攔截,又消費。

    輸出結(jié)果如下:

    I/Activity: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupA: onInterceptTouchEvent_ACTION_DOWNI/MyViewGroupB: dispatchTouchEvent_ACTION_DOWNI/MyViewGroupB: onInterceptTouchEvent_ACTION_DOWNI/MyViewGroupB: onTouchEvent_ACTION_DOWNI/Activity: dispatchTouchEvent_ACTION_MOVEI/MyViewGroupA: dispatchTouchEvent_ACTION_MOVEI/MyViewGroupA: onInterceptTouchEvent_ACTION_MOVEI/MyViewGroupB: dispatchTouchEvent_ACTION_MOVEI/MyViewGroupB: onTouchEvent_ACTION_MOVEI/Activity: dispatchTouchEvent_ACTION_UPI/MyViewGroupA: dispatchTouchEvent_ACTION_UPI/MyViewGroupA: onInterceptTouchEvent_ACTION_UPI/MyViewGroupB: dispatchTouchEvent_ACTION_UPI/MyViewGroupB: onTouchEvent_ACTION_UP

    結(jié)合輸出結(jié)果,總結(jié)如下:

    當觸發(fā)ACTION_DOWN的時候,依然從Activity開始向下傳遞,當?shù)竭_MyViewGroupB的是,因為在onInterceptTouchEvent進行了攔截操作,因此不再繼續(xù)向下分發(fā)傳遞,而是交由MyViewGroupB的onTouchEvent進行處理消費。MyViewGroupB的onTouchEvent返回的是true,說明它決定對ACTION_DOWN進行處理,因此事件也就不再移交上層處理。當觸發(fā)ACTION_MOVE和ACTION_UP的時候,事件還是從Activity開始向下傳遞,當?shù)竭_MyViewGroupB的時候,由于之前進行了攔截操作,因此,MyViewGroupB直接將事件分發(fā)給自己的onTouchEvent進行處理,不在向下分發(fā)傳遞。事件處理也不再向上層移交。

    三、文末

    事件分發(fā)機制就猶如數(shù)學的定理是一樣道理的,只有記住定理,才能在具體應用中具體分析,有人可能不知道在什么地方會用到,如果你做的項目中,比如有一個控件點擊不能反應,那么就有可能是事件分發(fā)的結(jié)果。

    至于對源碼的分析可能內(nèi)容比較復雜,內(nèi)容也多;需要我這套framework進階學習全套筆記的可以前往私信我;發(fā)送“核心筆記”或“手冊”即可領(lǐng)?。≌聿灰?!記得點贊分享哦!

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年7月9日 21:17
    下一篇 2022年7月9日 21:18

    相關(guān)推薦

    • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應該怎么發(fā))

      對于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營一個朋友圈,有的微商看起來逼格滿滿,實際效果也不錯;而有的卻動都不動就被屏蔽甚至拉黑…

      2022年11月27日
    • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

      寶可夢朱紫里有很多寶可夢都是擁有夢特性會變強的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

      2022年11月25日
    • 《寶可夢朱紫》奇魯莉安怎么進化?奇魯莉安進化方法分享

      寶可夢朱紫中的奇魯莉安要怎么進化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進化方法分享 奇魯莉安…

      2022年11月25日
    • 客服的崗位職責怎么寫(客服工作內(nèi)容及職責)

      各位小伙伴們大家周一好,又到了每周一給大家分享干貨內(nèi)容的時候啦~ 本期來跟大家分享一下客服工作管理流程以及客服崗位里面的每項職能崗位的核心細則,也是干貨滿滿推薦收藏~ 一.補償流程…

      2022年11月25日
    • 中興Axon40 Ultra航天版將于11月29日正式發(fā)布

      據(jù)中興手機官微爆料,中興Axon40 Ultra航天版將于11月29日正式發(fā)布,新機不僅會采用驍龍?zhí)幚砥?,還將為大家?guī)硪幻丢毩踩酒@得國密認證,擁有安全專利布局,不僅可以大…

      2022年11月24日
    • 三星tabs8+配置參數(shù) 三星tabs8+屏幕尺寸處理器介紹

      三星Galaxy Tab S8+是2022年3月份上市的一款平板,有很多用戶想了解一下這款平板的配置參數(shù),下面我就給大家提供一下這款平板的參數(shù)配置。 三星Galaxy Tab S8…

      2022年11月24日
    • 淘寶直播開通后帶貨鏈接怎么做(淘寶直播需要開通淘寶店鋪嗎)

      直播帶貨無論是對于商家來說還是主播收益都是非常可觀的,所以不少平臺都有直播帶貨功能,一些小伙伴也想加入淘寶直播,那么淘寶直播開通后帶貨鏈接怎么做?下面小編為大家?guī)硖詫氈辈ラ_通后帶…

      2022年11月24日
    • 事件營銷案例

      篇一成功營銷案例小故事成功銷售案例小故事篇1模仿 一個人想做一套家具,就走到樹林里砍倒一棵樹,并動手把它鋸成木板這個人鋸樹的時候,把樹干的一頭擱在樹墩上,自己騎在樹干上還往鋸開的縫…

      2022年11月24日
    • 《寶可夢朱紫》暴飛龍怎么抓?暴飛龍獲得方法

      寶可夢朱紫暴飛龍位置在哪?在游戲中,很多玩家還不清楚暴飛龍具體要怎么樣獲得,其實獲得方法很簡單,暴飛龍直接是沒得抓的,需要玩家從寶貝龍進化得到,下面一起來看一下寶可夢朱紫暴飛龍獲得…

      2022年11月23日
    • 《寶可夢朱紫》布土撥怎么進化?布土撥進化方法介紹

      寶可夢朱紫中,不同的寶可夢有不同的進化方法,其中布土撥的進化方法是比較特殊的。很多玩家不知道寶可夢朱紫布土撥怎么進化,下面就帶來寶可夢朱紫布土撥進化方法介紹,一起來看看吧,希望能幫…

      2022年11月23日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息