最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android事件分發(fā)機制的詳解

 更新時間:2017年09月21日 10:42:54   投稿:lqh  
這篇文章主要介紹了Android事件分發(fā)機制的詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握Android事件分發(fā)機制,需要的朋友可以參考下

Android事件分發(fā)機制

我們只考慮最重要的四個觸摸事件,即:DOWN,MOVE,UP和CANCEL。一個手勢(gesture)是一個事件列,以一個DOWN事件開始(當用戶觸摸屏幕時產(chǎn)生),后跟0個或多個MOVE事件(當用戶四處移動手指時產(chǎn)生),最后跟一個單獨的UP或CANCEL事件(當用戶手指離開屏幕或者系統(tǒng)告訴你手勢(gesture)由于其他原因結(jié)束時產(chǎn)生)。當我們說到“手勢剩余部分”時指的是手勢后續(xù)的MOVE事件和最后的UP或CANCEL事件。

在這里我也不考慮多點觸摸手勢(我們只假設(shè)用一個手指)并且忽略多個MOVE事件可以被歸為一組這一實際情況。最后,我們假設(shè)文中的view都沒有注冊onTouchListener。

我們將要討論的視圖層次是這樣的:最外層是一個ViewGroup A,包含一個或多個子view(children),其中一個子view是ViewGroup B,ViewGroupB中又包含一個或多個子view,其中一個子view是 View C,C不是一個ViewGroup。這里我們忽略同層級view之間可能的交叉疊加。


假設(shè)用戶首先觸摸到的屏幕上的點是C上的某個點,該點被標記為觸摸點(touch point),DOWN事件就在該點產(chǎn)生。然后用戶移動手指并最后離開屏幕,此過程中手指是否離開C的區(qū)域無關(guān)緊要,關(guān)鍵是手勢(gesture)是從哪里開始的。

默認情況

假設(shè)上面的A,B,C都沒有覆寫默認的事件傳播行為,那么下面就是事件傳播的過程:

  1. DOWN事件被傳到C的onTouchEvent方法中,該方法返回false,表示“我不關(guān)心這個手勢(gesture)”。
  2. 因此,DOWN事件被傳到B的onTouchEvent方法中,該方法同樣返回false,表示B也不關(guān)心這個手勢。
  3. 同樣,因為B不關(guān)心這個手勢,DOWN事件被傳到A的onTouchEvent方法中,該方法也返回false。

由于沒有view關(guān)心這個手勢(gesture),它們將不再會從“手勢剩余部分”中接收任何事件。

處理事件

現(xiàn)在,讓我們假設(shè)C實際上是關(guān)心這個手勢(gesture)的,原因可能是C被設(shè)置成可點擊的(clickable)或者你覆寫了C的onTouchEvent方法。

  • DOWN事件被傳遞給C的onTouchEvent方法,該方法可以做任何它想做的事情,最后返回true。
  • 因為C說它正在處理這個手勢(gesture),則DOWN事件將不再被傳遞給B和A的onTouchEvent方法。
  • 因為C說它正在處理這個手勢(gesture),所以“手勢剩余部分”的事件也將傳遞給C的onTouchEvent方法,此時該方法返回true或false都無關(guān)緊要了,但是為保持一致最好還是返回true。

個人理解:從這里可以看出,各個View的onTouchEvent方法對DOWN事件的處理,代表了該View對以此DOWN開始的整個手勢(gesture)的處理意愿,返回true代表愿意處理該gesture,返回false代表不愿意處理該gesture。

onInterceptTouchEvent

現(xiàn)在我們將討論一個新的方法:onInterceptTouchEvent,它只存在于ViewGroup中,普通的View中沒有這個方法。在任何一個view的onTouchEvent被調(diào)用之前,它的父輩們(ancestors)將先獲得攔截這個事件的一次機會,換句話說,它們可以竊取該事件。在剛才的“處理事件”部分中,我們遺漏了這一過程,現(xiàn)在,讓我們把它加上:

  • DOWN事件被傳給A的onInterceptTouchEvent,該方法返回false,表示它不想攔截。
  • DOWN又被傳遞給B的onInterceptTouchEvent,它也不想攔截,因此該方法也返回false。
  • 現(xiàn)在,DOWN事件被傳遞到C的onTouchEvent方法,該方法返回true,因為它想處理以該事件為首的手勢(gesture)。
  • 現(xiàn)在,該手勢的下一個事件MOVE到來了。這個MOVE事件再一次被傳遞給A的onInterceptTouchEvent方法,該方法再一次返回false,B也同樣如此。
  • 然后,MOVE事件被傳遞給C的onTouchEvent,就像在前一部分中一樣。
  • “手勢剩余部分”中其他事件的處理過程和上面一樣,假如A和B的onInterceptTouchEvent方法繼續(xù)返回false的話。       這里有兩點需要注意:
  • 雖然ViewGroup A和B的onInterceptTouchEvent方法對DOWN事件返回了false,后續(xù)的事件依然會傳遞給它們的onInterceptTouchEvent方法,這一點與onTouchEvent的行為是不一樣的。
  • 假如DOWN事件傳給C的onTouchEvent方法時,它返回了false,DOWN事件會繼續(xù)向上傳遞給B和A的onTouchEvent,即使它們在onInterceptTouchEvent方法中說它們不想攔截這個DOWN事件,但沒辦法,沒有子View愿意處理該事件。

個人理解:感謝@編程世界的孩子 的提醒,由此可見,DOWN事件的處理實際上經(jīng)歷了一下一上兩個過程,下是指A->B的onInterceptTouchEvent,上是指C->B->A的onTouchEvent,當然,任意一步的方法中返回true,都能阻止它繼續(xù)傳播。

攔截事件

現(xiàn)在,讓我們更進一步,假設(shè)B沒有攔截DOWN事件,但它攔截了接下來的MOVE事件。原因可能是B是一個scrolling view。當用戶僅僅在它的區(qū)域內(nèi)點擊(tap)時,被點擊到的元素應(yīng)當能處理該點擊事件。但是當用戶手指移動了一定的距離后,就不能再視該手勢(gesture)為點擊了——很明顯,用戶是想scroll。這就是為什么B要接管該手勢(gesture)。
下面是事件被處理的順序:

  • DOWN事件被依次傳到A和B的onInterceptTouchEvent方法中,它們都返回的false,因為它們目前還不想攔截。
  • DOWN事件傳遞到C的onTouchEvent方法,返回了true。
  • 在后續(xù)到來MOVE事件時,A的onInterceptTouchEvent方法仍然返回false。
  • B的onInterceptTouchEvent方法收到了該MOVE事件,此時B注意到用戶手指移動距離已經(jīng)超過了一定的threshold(或者稱為slop)。因此,B的onInterceptTouchEvent方法決定返回true,從而接管該手勢(gesture)后續(xù)的處理。
  • 然后,這個MOVE事件將會被系統(tǒng)變成一個CANCEL事件,這個CANCEL事件將會傳遞給C的onTouchEvent方法。
  • 現(xiàn)在,又來了一個MOVE事件,它被傳遞給A的onInterceptTouchEvent方法,A還是不關(guān)心該事件,因此onInterceptTouchEvent方法繼續(xù)返回false。
  • 此時,該MOVE事件將不會再傳遞給B的onInterceptTouchEvent方法,該方法一旦返回一次true,就再也不會被調(diào)用了。事實上,該MOVE以及“手勢剩余部分”都將傳遞給B的onTouchEvent方法(除非A決定攔截“手勢剩余部分”)。
  • C再也不會收到該手勢(gesture)產(chǎn)生的任何事件了。

下面的一些小事情可能會令你感到吃驚:

  • 如果一個ViewGroup攔截了最初的DOWN事件,該事件仍然會傳遞到該ViewGroup的onTouchEvent方法中。
  • 另一方面,如果ViewGroup攔截了一個半路的事件(比如,MOVE),這個事件將會被系統(tǒng)變成一個CANCEL事件,并傳遞給之前處理該手勢(gesture)的子View,而且不會再傳遞(無論是被攔截的MOVE還是系統(tǒng)生成的CANCEL)給ViewGroup的onTouchEvent方法。只有再到來的事件才會傳遞到ViewGroup的onTouchEvent方法中。

從此開始,你可以更進一步。比如對mouthful-method (實在不知道該怎么翻譯啦!)requestDisallowInterceptTouchEvent,C可以用該方法阻止B竊取事件。如果你想更加瘋狂一點,你可以在你自己的ViewGroup中直接覆寫dispatchTouchEvent方法,并對傳遞進來的事件做任何你想做的處理。但這樣的話你可能會破壞一些約定,所以應(yīng)當小心。

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Android實現(xiàn)短信驗證功能的代碼

    Android實現(xiàn)短信驗證功能的代碼

    這篇文章主要介紹了Android實現(xiàn)短信驗證功能的代碼的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • Flutter實現(xiàn)矩形取色器的封裝

    Flutter實現(xiàn)矩形取色器的封裝

    這篇文章主要為大家詳細介紹了Flutter實現(xiàn)矩形取色器的封裝,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Android使用CoordinatorLayout實現(xiàn)底部彈出菜單

    Android使用CoordinatorLayout實現(xiàn)底部彈出菜單

    這篇文章主要為大家詳細介紹了Android使用CoordinatorLayout實現(xiàn)底部彈出菜單,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android中HttpURLConnection類使用介紹

    Android中HttpURLConnection類使用介紹

    早些時候其實我們都習(xí)慣性使用HttpClient,但是后來Android6.0之后不再支持HttpClient,需要添加Apache的jar才行,所以,就有很多開發(fā)者放棄使用HttpClient了,HttpURLConnection畢竟是標準Java接口(java.net) ,適配性還是很強的
    2022-12-12
  • Android手勢ImageView三部曲 第二部

    Android手勢ImageView三部曲 第二部

    這篇文章主要為大家詳細介紹了Android手勢ImageView三部曲的第二部,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android創(chuàng)建與解析XML(二)——詳解Dom方式

    Android創(chuàng)建與解析XML(二)——詳解Dom方式

    本篇文章主要介紹了Android創(chuàng)建與解析XML(二)——詳解Dom方式 ,這里整理了詳細的代碼,有需要的小伙伴可以參考下。
    2016-11-11
  • Android中View位置和觸摸事件詳解

    Android中View位置和觸摸事件詳解

    這篇文章主要給大家介紹了關(guān)于Android中View位置和觸摸事件的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Android與單片機通信常用數(shù)據(jù)轉(zhuǎn)換方法總結(jié)

    Android與單片機通信常用數(shù)據(jù)轉(zhuǎn)換方法總結(jié)

    本文主要介紹Android與單片機通信常用數(shù)據(jù)轉(zhuǎn)換方法,這里提供了代碼示例,有需要的小伙伴可以參考下
    2016-09-09
  • Android使用http實現(xiàn)注冊登錄功能

    Android使用http實現(xiàn)注冊登錄功能

    這篇文章主要為大家詳細介紹了Android使用http實現(xiàn)注冊登錄功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android TelephonyManager詳解及實現(xiàn)代碼

    Android TelephonyManager詳解及實現(xiàn)代碼

    本文主要介紹Android TelephonyManager, 這里整理了關(guān)于Android TelephoneManager的相關(guān)資料,并附有示例代碼和實現(xiàn)效果圖,有需要的朋友可以參考下
    2016-08-08

最新評論

北川| 瑞昌市| 沛县| 衡南县| 通榆县| 文安县| 镇沅| 红安县| 永城市| 景德镇市| 巩留县| 含山县| 五指山市| 深水埗区| 太仓市| 永吉县| 内乡县| 龙门县| 滦南县| 平泉县| 无为县| 固始县| 台山市| 巫溪县| 新丰县| 章丘市| 丰宁| 东乌珠穆沁旗| 陈巴尔虎旗| 阿拉善右旗| 右玉县| 青海省| 阜城县| 平和县| 正蓝旗| 贡觉县| 通海县| 江山市| 广灵县| 柳河县| 巴中市|