1.觸屏事件對象
是通過MotionEvent 對象進行封裝的,常用的事件類型是定義在MotionEvent 中的常量。我們通過getActionMasked() 方法。
getAction()與getActionMasked()
getAction()和getActionMasked()都是用來獲取事件的信息。
不同的是getAction()可以獲得事件的指針ID和類型信息。
getActionMasked()只簡單返回事件類型的信息,正如其名稱,
它“屏蔽”了某些信息的返回,但我們可以通過getPointerIndex()在同一個事件中獲取相應指針信息。
指針作用的實質是匹配事件到接觸點的一種方式。
這兩個方法返回值是一個位字段,即事件類型和指針信息包含在返回的
同一個整型數據中,安卓有定義可以提取它的信息。
舉個例子:
getAction() 返回 0x0105.
getActionMasked() 返回 0x0005, 它包含了 0x0105 和 ACTION_MASK 信息。
1.ACTION_MASK的值爲0xFF。它掩蓋了以下措施。
ACTION_DOWN 0, UP 1, MOVE 2
ACTION_POINTER_DOWN 5, UP 6
2.ACTION_POINTER_ID_MASK的值是爲0xFF00。它從以下已過時常量掩蓋指針ID。
ACTION_POINTER_1_DOWN 0x0005
ACTION_POINTER_2_DOWN 0x0105
ACTION_POINTER_3_DOWN 0x0205
...
那麼有什麼區別呢?在使用getAction()時,我們經常需要分離出返回值中的信息,
可通過getActionMasked() 和 getActionIndex()
獲取其中的信息,因此當它被分離,可能要較高的運行成本,
因爲這兩個獨立的方法又被調用。另外touch API也存儲了近期觸摸事件歷史信息,
所以返回的數據中可能包含更多的信息。
2.點擊監聽器(onClickListener)
使用view.performClick ()方法可以調用view的onClickListener監聽器對象,當其有定義的時候。當指定的onClickListener()存在時,返回true.否則返回false。它會執行一切與點擊有關的動作。
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
view.performClick();
int actionType = motionEvent.getActionMasked();
int index = motionEvent.getActionIndex();
switch(actionType){
case MotionEvent.ACTION_DOWN:
...
return true;
case MotionEvent.ACTION_MOVE:
//由於ACTION_MOVE包含較多的信息,因此自定義一個方法專門處理該事件
handleMove(motionEvent);
return true;
case MotionEvent.ACTION_UP:
...
return true;
case MotionEvent.ACTION_POINTER_DOWN:
...
return true;
case MotionEvent.ACTION_POINTER_UP:
...
return true;
}
return false;
}
3.MotionEvent屬性
MotionEvent 通過動作代碼和數值集合來敘述事件。動作代碼指定狀態改變,數值集描述座標和其他運動屬性。
MotionEvent定義了一些常量來指示運動狀態:ACTION_DOWN,ACTION_UP,ACTION_POINTER_DOWN,ACTION_POINTER_UP等等
ACTION_DOWN和ACTION_UP分別是屏幕上的第一個指針,和最後一個指針
而ACTION_POINTER_DOWN和ACTION_POINTER_UP則是其中後續加入或倒數退出的指針
另外在一個運動事件中每個指針出現的順序是不一定連續的,指針ID是有指針第一次觸及到屏幕時就分配的唯一的ID,而指針索引隨着指針運動的變化而變化,它的範圍是從0到MotionEvent.getPointerCount()-1之間,而且最後的一個指針索引都是0,比如第一個指針先觸及到屏幕,系統分配給它的指針索引是0,第二個指針後觸及到屏幕,系統分配給它的指針索引是1。當我們先把第一個指針從屏幕移開後,屏幕上只剩下第二根指針,這時第二根的指針就不再是1,而是0,指針索引會隨着手指的按下和提起不斷變化。
4.MotionEvent行爲
事件通過實現onTouchListener接口監聽觸屏行爲,View.OnTouchListener 的定義是在觸摸事件調度到組件時調用回調接口,這個回調會在觸摸到事件前被調用。onTouch()是當事件調度到組件時被調用,它允許監聽器獲得一個機會響應在觸發目標組件之前。在onTouch()方法中通過View.performClick()方法調用View的OnTouchLishtener接口。
public boolean onTouch(View v,MotionEvent event){
v.performClick();
...
}
onTouch函數返回值如果爲true,則表示該事件已經被組件處理,不需要將這個事件分發給其他處理;如果返回false,則表示這個組件未處理,安卓應該將該事件分發給其它處理。
onTouch() vs onTouchEvent()
onTouch()需要兩個參數(View v, MotionEvent e)可以在任何類中使用時,需要3個步驟:
1.實現onTouchListener接口
2.這個類使用view.setOnTouchListener(foo)註冊監聽器
3.重寫onTouch()方法。
而onTouchEvent只需要一個參數(MotionEvent e),它需要在view類和其派生類中使用,使用它時比onTouch()少1和2兩個步驟,
它是由安卓系統實現的,因此直接重寫onTouchEvent()方法即可。
此外:onTouch()的優先級比onTouchEvent()的優先級更高,當onTouch返回false時纔會把事件交付到onTouchEvent來處理。
5.多點觸摸
在多點觸摸情況下處理TOUCH_MOVE動作代碼,因爲你可能在單一事件中有多個指針,爲了獲取正確的指針ID,你需要遍歷存在的指針,需使用下面的代碼:
for(int i = 0; i < event.getPointerCount(); i++){
int curPointerId = event.getPointerId(i);
}
歷史點:對於ACTON_MOVE事件,不僅指針有一系列事件,同時從你最後調用方法以來也產生了更多的ACTION_MOVE事件。Android緩存了這期間onTouchEvent方法爲ACTION_MOVE動作的後續調用發生的事件,爲了獲得這些事件,你必須使用下面的代碼:
for(int j = 0; j < event.getHistorySize(); j++)
{
for(int i = 0; i < event.getPointerCount(); i++)
{
int curPointerId = event.getPointerId(i);
// 爲了得到該事件的歷史數據
// 你必須使用getHistorical...方法
int x = event.getHistoricalX(i, j);
}
}
MotionEvent中常用到的方法:
getPointerCount():返回MotionEvent中表示了多少手指數
getPointerId(int pointerIndex): 返回指針索引關聯的指針ID
getY(int pointerIndex):返回指定指針索引的當前的Y座標位置
getX(int pointerIndex):返回指定指針索引的當前的X座標位置
getHistorySize():返回某根手指觸摸事件的歷史位置的記錄數,發生在MotionEvent.ACTION_MOVE事件的一次移動的之間
getHistoricalX (int pointerIndex, int pos):返回指定指針索引的手指上一次的X座標位置,只針對移動事件。參數pos是指第幾個舊位置,這個值不能超過getHistorySize()返回的值
getHistoricalY (int pointerIndex, int pos):返回指定指針索引的手指上一次的Y座標位置,只針對移動事件。參數pos是指第幾個舊位置,這個值不能超過getHistorySize()返回的值