今天在做拖動View使其跟隨手指移動的Demo時,用了getX()和getRawX()兩種方法來實現,

getX()的方法實現:

public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        Log.e(TAG, "onTouchEvent: " + x +"---" + y);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 記錄觸控點座標
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                // 計算偏移量
                int offsetX = x - lastX;
                int offsetY = y - lastY;
                // 在當前left,top,right,bottom的基礎上加上偏移量
                // view會呼叫layout方法,layout中會呼叫onLayout方法,正常情況下我們重寫onLayout就可以了
                layout(getLeft() + offsetX,
                        getTop() + offsetY,
                        getRight() + offsetX,
                        getBottom() + offsetY);
//                offsetLeftAndRight(offsetX);
//                offsetTopAndBottom(offsetY);
                break;
        }
        return true;
    }
getRawX()的方法實現:
// 絕對座標方式

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 記錄觸控點座標
                lastX = rawX;
                lastY = rawY;
                break;
            case MotionEvent.ACTION_MOVE:
                // 計算偏移量
                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;
                // 在當前left,top,right,bottom的基礎上加上偏移量
                layout(getLeft() + offsetX,
                        getTop() + offsetY,
                        getRight() + offsetX,
                        getBottom() + offsetY);
                // 重新設定初始座標
                lastX = rawX;
                lastY = rawY;
                break;
        }
        return true;
    }
我們可以看到兩者間的區別:getRawX()的方法要在ACTION_MOVE的最後重新設定初始座標。

原因:

getX()獲取的是當前相對於觸控的View的座標,在ACTION_MOVE中將View偏移後,下一次觸發onTouchEvent的時候,event.getX()已經自動隨著View的更改而調整了位置,所以無需手動重新設定初始座標。

而getRawX()獲取的是相對於整個螢幕的絕對座標ACTION_MOVE中將View偏移後,下一次觸發onTouchEvent的時候,event.getRawX()並沒有獲取的依然是螢幕絕對座標,如果這時不手動重新設定座標,那麼偏移量會大大增加。

自己慢慢體會。