Search code examples
androidsurfaceviewtouch-event

How to move an object on a SurfaceView without touching the object itself?


I found this question, but it's for iOS development. I'm doing something in Android, so it wasn't any help.

I have a simple white rectangle on a black canvas, and I have an onTouchEvent set up. I can move the rectangle as expected, but this is not the functionality I'm looking for.

I'm needing to know how I can touch anywhere on the screen and move an object? I don't want the object's X and Y to become my touch event's getX() and getY().

For now, I have:

@Override
public boolean onTouchEvent(MotionEvent event) {

    switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            myPoint.set((int)event.getX(), (int)event.getY());
    }
    return true;
}

My reasoning for this is so the object can be seen without a finger hovering over it. Is this possible?

Here is a visual representation of what I'm wanting to achieve:

onTouch example


Solution

  • Why not get and store the previous MotionEvent coordinates in the onTouchEvent callback, then when onTouchEvent fires again (first ACTION_MOVE after ACTION_DOWN and then so on for each ACTION_MOVE callback) work out the offset/difference between the values then get your own myPoint coordinates and add the offset to their current values. This way you're only moving the myPoint object by the position offset, not the actual coordinates.

    This code isn't tested and I've not used an IDE but something like this:

    private float oldX;
    private float oldY;
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                oldX = event.getX();
                oldY = event.getY();
                break;
    
            case MotionEvent.ACTION_MOVE:
                float newX = event.getX();
                float newY = event.getY();
                float offsetX = getOffset(oldX, newX, myPoint.x);
                float offsetY = getOffset(oldY, newY, myPoint.y);
    
                myPoint.set((int) offsetX, (int) offsetY);
    
                oldX = newX;
                oldY = newY;
                break;
        }
        return true;
    }
    
    private float getOffset(float oldVal, float newVal, float current) {
        return current + (newVal - oldVal);
    }