您好,登錄后才能下訂單哦!
Android事件分發機制
我們只考慮最重要的四個觸摸事件,即:DOWN,MOVE,UP和CANCEL。一個手勢(gesture)是一個事件列,以一個DOWN事件開始(當用戶觸摸屏幕時產生),后跟0個或多個MOVE事件(當用戶四處移動手指時產生),最后跟一個單獨的UP或CANCEL事件(當用戶手指離開屏幕或者系統告訴你手勢(gesture)由于其他原因結束時產生)。當我們說到“手勢剩余部分”時指的是手勢后續的MOVE事件和最后的UP或CANCEL事件。
在這里我也不考慮多點觸摸手勢(我們只假設用一個手指)并且忽略多個MOVE事件可以被歸為一組這一實際情況。最后,我們假設文中的view都沒有注冊onTouchListener。
我們將要討論的視圖層次是這樣的:最外層是一個ViewGroup A,包含一個或多個子view(children),其中一個子view是ViewGroup B,ViewGroupB中又包含一個或多個子view,其中一個子view是 View C,C不是一個ViewGroup。這里我們忽略同層級view之間可能的交叉疊加。
假設用戶首先觸摸到的屏幕上的點是C上的某個點,該點被標記為觸摸點(touch point),DOWN事件就在該點產生。然后用戶移動手指并最后離開屏幕,此過程中手指是否離開C的區域無關緊要,關鍵是手勢(gesture)是從哪里開始的。
默認情況
假設上面的A,B,C都沒有覆寫默認的事件傳播行為,那么下面就是事件傳播的過程:
由于沒有view關心這個手勢(gesture),它們將不再會從“手勢剩余部分”中接收任何事件。
處理事件
現在,讓我們假設C實際上是關心這個手勢(gesture)的,原因可能是C被設置成可點擊的(clickable)或者你覆寫了C的onTouchEvent方法。
個人理解:從這里可以看出,各個View的onTouchEvent方法對DOWN事件的處理,代表了該View對以此DOWN開始的整個手勢(gesture)的處理意愿,返回true代表愿意處理該gesture,返回false代表不愿意處理該gesture。
onInterceptTouchEvent
現在我們將討論一個新的方法:onInterceptTouchEvent,它只存在于ViewGroup中,普通的View中沒有這個方法。在任何一個view的onTouchEvent被調用之前,它的父輩們(ancestors)將先獲得攔截這個事件的一次機會,換句話說,它們可以竊取該事件。在剛才的“處理事件”部分中,我們遺漏了這一過程,現在,讓我們把它加上:
個人理解:感謝@編程世界的孩子 的提醒,由此可見,DOWN事件的處理實際上經歷了一下一上兩個過程,下是指A->B的onInterceptTouchEvent,上是指C->B->A的onTouchEvent,當然,任意一步的方法中返回true,都能阻止它繼續傳播。
攔截事件
現在,讓我們更進一步,假設B沒有攔截DOWN事件,但它攔截了接下來的MOVE事件。原因可能是B是一個scrolling view。當用戶僅僅在它的區域內點擊(tap)時,被點擊到的元素應當能處理該點擊事件。但是當用戶手指移動了一定的距離后,就不能再視該手勢(gesture)為點擊了——很明顯,用戶是想scroll。這就是為什么B要接管該手勢(gesture)。
下面是事件被處理的順序:
下面的一些小事情可能會令你感到吃驚:
從此開始,你可以更進一步。比如對mouthful-method (實在不知道該怎么翻譯啦!)requestDisallowInterceptTouchEvent,C可以用該方法阻止B竊取事件。如果你想更加瘋狂一點,你可以在你自己的ViewGroup中直接覆寫dispatchTouchEvent方法,并對傳遞進來的事件做任何你想做的處理。但這樣的話你可能會破壞一些約定,所以應當小心。
如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。