Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android觸控基礎:MotionEvent

Android觸控基礎:MotionEvent

編輯:關於Android編程

之前的文章層從Framework層介紹了Android Touch事件即(MotionEvent)的傳遞機制。本文將詳細介紹MotionEvent的一些成員和方法。了解了MotionEvent對開發一些特效如拖動控件或多點縮放控件有很大的作用。同時,掌握MotionEvent類也是學好android觸控技術的基礎。

一、一些常量

常見的動作常量:

public static final int ACTION_DOWN = 0;單點觸摸動作

public static final int ACTION_UP = 1;單點觸摸離開動作
public static final int ACTION_MOVE = 2;觸摸點移動動作
public static final int ACTION_CANCEL = 3;觸摸動作取消
public static final int ACTION_OUTSIDE = 4;觸摸動作超出邊界
public static final int ACTION_POINTER_DOWN = 5;多點觸摸動作
public static final int ACTION_POINTER_UP = 6;多點離開動作
以下是一些非touch事件
public static final int ACTION_HOVER_MOVE = 7;
public static final int ACTION_SCROLL = 8;
public static final int ACTION_HOVER_ENTER = 9;
public static final int ACTION_HOVER_EXIT = 10;

掩碼常量

ACTION_MASK = 0X000000ff 動作掩碼
ACTION_POINTER_INDEX_MASK = 0X0000ff00 觸摸點索引掩碼

ACTION_POINTER_INDEX_SHIFT = 8 獲取觸摸點索引需要移動的位數


二、相關方法

getAction()方法返回的是int類型,用到的只有低16位,其中:低八位是動作的類型,高8位是觸摸點索引值的表示(單點為0,雙點為1)

獲得動作類型: int action = event.getAction() & ACTION_MASK 或者使用 getActionMasked()

獲得觸摸點索引類型: int pointerIndex = (event.getAction() & ACTION_POINTER_INDEX_MASK ) >> ACTION_POINTER_INDEX_SHIFT

或者使用 getActionIndex()

為什麼要有索引信息?

有了索引信息,我們可以在onTOuchEvent事件中判斷傳進來的MotionEvent對象對應的是單點信息還是多點信息。

下面的代碼段能使用戶在屏幕上拖動一個對象。它記錄了初始點的位置,計算點移動的距離,並將對象移動到新的位置。它正確的處理了這種情況:當第一個手指把控件拖到一個位置,然後按下第二個手指,且第二個手指與同一個控件上。當用戶抬起第一個手指時,控件不會跑到第二個手指的位置同時第二個手指可以繼續拖動控件。

// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Let the ScaleGestureDetector inspect all events.
    mScaleDetector.onTouchEvent(ev);
             
    final int action = MotionEventCompat.getActionMasked(ev); 
        
    switch (action) { 
    case MotionEvent.ACTION_DOWN: {
        final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
        final float x = MotionEventCompat.getX(ev, pointerIndex); 
        final float y = MotionEventCompat.getY(ev, pointerIndex); 
            
        // Remember where we started (for dragging)
        mLastTouchX = x;
        mLastTouchY = y;
        // Save the ID of this pointer (for dragging)
        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        break;
    }
            
    case MotionEvent.ACTION_MOVE: {
        // Find the index of the active pointer and fetch its position
        final int pointerIndex = 
                MotionEventCompat.findPointerIndex(ev, mActivePointerId);  
            
        final float x = MotionEventCompat.getX(ev, pointerIndex);
        final float y = MotionEventCompat.getY(ev, pointerIndex);
            
        // Only move if the ScaleGestureDetector isn't processing a gesture.
        if (!mScaleDetector.isInProgress()) {
            // Calculate the distance moved
            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;

            invalidate();
        }
        // Remember this touch position for the next move event
        mLastTouchX = x;
        mLastTouchY = y;

        break;
    }
            
    case MotionEvent.ACTION_UP: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }
            
    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }
        
    case MotionEvent.ACTION_POINTER_UP: {
            
        final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
        final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); 

        if (pointerId == mActivePointerId) {
            // This was our active pointer going up. Choose a new
            // active pointer and adjust accordingly.
            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex); 
            mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex); 
            mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
        }
        break;
    }
    }       
    return true;
}

MotionEvent還包含了移動操作中其它歷史移動數據以方便處理觸控的移動操作.

android sdk對於這個類的描述中就有這麼一句:

For efficiency, motion events with ACTION_MOVE may batch together multiple movement samples within a single object.



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved