首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 多點觸控實作:同時顯示多手指觸摸波紋效果

     編輯:程式設計綜合問答

問題核心

原代碼在 onTouchEvent 中僅處理 ACTION_DOWN 與 ACTION_POINTER_DOWN,但 座標獲取方式錯誤:event.getX()/getY() 無參數呼叫永遠返回**第一個指標 (index 0)** 的座標,導致多指觸控時只在第一根手指位置繪製波紋。

正確多點觸控座標獲取模式

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getActionMasked(); // 使用 getActionMasked() 區分動作類型
    int pointerIndex = event.getActionIndex(); // 觸發此事件的具體指標索引
    int pointerId = event.getPointerId(pointerIndex); // 該指標的唯一 ID (追蹤用)

    switch (action) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN: {
            // 取得**該指標**的座標
            float x = event.getX(pointerIndex);
            float y = event.getY(pointerIndex);
            addPoint((int)x, (int)y, pointerId); // 建議傳入 pointerId 以便追蹤
            break;
        }
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL: {
            // 手指抬起,可選移除對應 pointerId 的波紋或標記結束
            // removePoint(pointerId); 
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            // 多指移動需遍歷所有有效指標
            for (int i = 0; i < event.getPointerCount(); i++) {
                int id = event.getPointerId(i);
                float x = event.getX(i);
                float y = event.getY(i);
                // updatePoint(id, x, y); // 若需拖動波紋
            }
            break;
        }
    }
    return true; // 返回 true 表示消費事件,繼續接收後續 MOVE/UP
}

關鍵修正點總結

錯誤寫法正確寫法說明
event.getX()event.getX(pointerIndex)必須指定指標索引,否則永遠取第一根手指
switch event.getAction() & MASKevent.getActionMasked()API 8+ 建議用獨立方法,更清晰
未使用 pointerId儲存 pointerId 對應波紋物件索引可能因手指增減而變動,ID 才是穩定識別碼
未處理 ACTION_MOVE遍歷 getPointerCount() 更新所有點支援拖動效果的必要邏輯

波紋管理資料結構建議

將 ArrayList<myWave> 改為 SparseArray<myWave> 或 HashMap<Integer, myWave>,Key 為 pointerId,Value 為波紋物件,實現 O(1) 增刪查,避免陣列移除導致索引錯亂。

完整流程圖解

  1. 手指按下 → ACTION_DOWN / POINTER_DOWN → 取得 pointerIndex → getX(pointerIndex) → 建立波紋物件存入 Map(key=pointerId) → invalidate() 觸發重繪。
  2. 手指移動 → ACTION_MOVE → 遍歷所有 pointerIndex → 更新 Map 中對應波紋座標 → invalidate()。
  3. 手指抬起 → ACTION_UP / POINTER_UP → 從 Map 移除該 pointerId → (可選) 啟動淡出動畫 → invalidate()。

掌握 ActionMasked + ActionIndex + PointerId + getX(index) 這組「四大金剛」,即可輕鬆實作任意多點觸控互動效果。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved