Search code examples
javaandroidontouchlistener

onTouchListener ACTION_MOVE not working with more than 1 finger


I'm building an OpenGL ES app and I use an onTouchListener to detect touch events, as suggested by the android development website (https://developer.android.com/training/gestures/multi#java). I then call other functions to handle the touch events. But the thing is, my other functions tell me that the second pointer(or further pointers) never calls ACTION_MOVE. I didn't see this issue beeing mentioned anywhere, not even on StackOverFlow, so if you know what could be causing this issue, please tell me.

Here's the code:

public class GluSurfaceView extends GLSurfaceView {

    final com.glu.engine.Renderer renderer;

    @SuppressLint("ClickableViewAccessibility")
    public GluSurfaceView(Context context, AppCompatActivity main) {
        super(context);

        setEGLContextClientVersion(3);
        renderer = new com.glu.engine.Renderer(main);
        setRenderer(renderer);

        setOnTouchListener((view, motionEvent) -> {
            int ID = MotionEventCompat.getActionIndex(motionEvent);
            if(motionEvent.getActionMasked() == MotionEvent.ACTION_MOVE){
                //recorAction records a new Pointer's position
                renderer.recordAction(ID, motionEvent.getX(ID),motionEvent.getY(ID));
                Log.w("OnTouchListener","we recorded a change! "+ID+" has moved.");
                return true;
            }

            if(motionEvent.getActionMasked() == MotionEvent.ACTION_UP){
                //stopAction let's the program know that an action has stopped
                renderer.stopAction(0);
                Log.w("onTouchListener","first Action stopped");
                return true;
            }

            if(motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN){
                //startAction let's the program know to start a knew array to store Pointers positions
                renderer.startAction(0);
                renderer.recordAction(0,motionEvent.getX(0),motionEvent.getY(0));
                Log.w("onTouchListener","first Action!");
                return true;
            }
            if(motionEvent.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN){
                renderer.addPointer(ID);
                renderer.recordAction(ID,motionEvent.getX(ID),motionEvent.getY(ID));
                Log.w("onTouchListener","new Action! "+ID);
                return true;
            }
            if(motionEvent.getActionMasked() == MotionEvent.ACTION_POINTER_UP) {
                renderer.removePointer(ID);
                Log.w("onTouchListener","action "+ID+" has stopped.");
                return true;
            }
            return false;
        });
    }
}

and here's the log:

E/actionManager: addedAction 0. actionNumber: 1 isTouching: true // this one is called in renderer
W/onTouchListener: first Action!
W/OnTouchListener: we recorded a change! 0 has moved.
E/actionManager: addedAction 1. actionNumber: 2 isTouching: true
W/onTouchListener: new Action! 1
W/OnTouchListener: we recorded a change! 0 has moved.
W/OnTouchListener: we recorded a change! 0 has moved.
W/OnTouchListener: we recorded a change! 0 has moved.
[same thing for a while...]
W/OnTouchListener: we recorded a change! 0 has moved.
W/OnTouchListener: we recorded a change! 0 has moved.
W/OnTouchListener: we recorded a change! 0 has moved.
E/actionManager: stopped action 1. actionNumber: 1 isTouching: false
W/onTouchListener: action 1 has stopped.
W/OnTouchListener: we recorded a change! 0 has moved.
W/OnTouchListener: we recorded a change! 0 has moved.
E/actionManager: stopped action 0. actionNumber: 0 isTouching: false
W/onTouchListener: first Action stopped

You can see that ACTION_MOVE is never called by action 1. Why could that be? And can I fix it?


Solution

  • Turns out it was mentioned here. Thanks @EleventhPrime. Also, after some thinking, I didn't need to update only one pointer at a time when the system wants it, I can update them all at once!

    for(int i = 0; i < motionEvent.getPointerCount(); i++) {
        int Index = motionEvent.findPointerIndex(motionEvent.getPointerId(i));
        renderer.recordAction(motionEvent.getPointerId(i), motionEvent.getX(Index), motionEvent.getY(Index));
        Log.w("OnTouchListener", "we recorded a change! " + i + " has moved.");
    }