在很多自定義View的場景中,都有可能需要重寫onTouchEvent、dispatchTouchEvent等方法,這些方法都傳入壹個MotionEvent對象,壹般來說,我們需要通過該MotionEvent對象來獲取當前的手勢動作,然後判斷Action_Down、Action_Move、Action_Up來執行不同的操作邏輯。
但是當我們看MotionEvent對象時,發現它有getAction、getActionMask和getActionIndex方法,而且在我們看第三方源碼時,經常會看到這樣的寫法:
同時也會看到這樣的寫法:
這兩種寫法到底有什麽區別呢?我們就來說壹下MotionEvent的幾種獲取Action信息的方法。
Android用壹個32位的整數值來表示壹個TouchEvent事件,低8位表示Touch事件的具體動作,例如按下、擡起、移動等動作。高8位表示Touch事件中多點觸控的索引值。
從源碼可以看出getActionMasked = getAction & MotionEvent.ACTION_MASK
而MotionEvent.ACTION_MASK 是壹個常量值,值為0xff,所以getActionMasked方法只保留了低8位的信息,也就是說只保留了觸摸的動作信息。
為什麽看第三方源碼時,有時候寫getAction,有時候寫getActionMasked呢?從上面的分析中可以看出來個所以然:
getAction表示觸摸動作的原始32位信息,當沒有多點觸控時,高8位即為0,這個時候getAction == getActionMasked。所以當我們確定我們自定義的View不會使用到多點觸控時,就可以直接使用 getAction 來表示具體的觸摸動作。但如果需要使用多點觸控,或者是不確定後面會不會使用多點觸控,則使用 getActionMasked 則是最保險的操作,所以我們經常看到下面這兩種寫法:
Android中是支持多點觸控的,那麽在高8位中是如何存儲多點觸控的索引信息的呢?舉個例子來說:
如果從getAction方法中返回的值是0x0000,則表示是第壹個觸控點的ACTION_DOWN操作。高8位是0表示第壹個觸控點,低8位是0表示ACTION_DOWN操作。
同理,如果返回值是0x0100,則表示第二個觸控點的ACTION_DOWN操作。
也就是說,getAction返回值的低8位表示觸摸動作的類型信息,而高8位表示觸控點的索引信息,也就是哪壹個觸控點的事件。