So I'm developing an application that must handle multitouch. Basically I want single touch for rotating ( this is no problem ). And multitouch for scrolling.
I have the basic code in, but I'm having problems when the shift from single to multitouch, and vice verca, occur. Basically the movement will jolt because the median position of the multitouch ( two fingers ) and the absolute position of the single finger are at a distance. So if I have two fingers on the screen, they make up a median position, and then lift one finger, it would be like a quick movement from that median position to the absolute single finger position. This will be the movement that I don't want.
This is my code:
@Override
public boolean onTouchEvent( MotionEvent event ) {
float xEvent[] = new float[ 2 ];
float yEvent[] = new float[ 2 ];
switch( event.getPointerCount() ) {
case 1:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchRotate( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
case 2:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
xEvent[ 1 ] = event.getX( 1 );
yEvent[ 1 ] = event.getY( 1 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchSlide( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_POINTER_1_UP:
camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
return true;
case MotionEvent.ACTION_POINTER_2_UP:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
default: return false;
}
}
The onTouchDown function of the camera just sets the first value of the touch move. That's why I also use it in the up movement to set a new begin value for the single touch movement when coming from a multitouch.
I hope someone knows what my problem is and can help me further.
Start here if you haven't read it already, it goes over a number of things dealing with multitouch in Android: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
A few things about your posted code:
ACTION_DOWN
with a pointer count of 2. ACTION_DOWN
is only sent for the first pointer that goes down. All fingers that touch the screen after the first will send ACTION_POINTER_DOWN
.MotionEvent#getActionMasked()
) than to code for each pointer index individually.MotionEvent
. If you're tracking pointer movement over time, use the pointer ID.You can solve this with simple math, although there may be a better way already built in.
Just create an object that holds the position of each finger when the .ACTION_POINTER_X_UP event fires and a boolean object that holds which type of touchmode you last used.
case MotionEvent.ACTION_POINTER_1_UP:
camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
boolean usedMultiTouch = true;
int x = event.getX(1);
int y = event.getY(1);
return true;
Next your ACTION_MOVE (inside the case=1) statement will fire as the user moves their finger as they went from multi to single touch.
Now, depending on what you want to do, you can either ignore the single move (the boolean is your check) until the .ACTION_UP event fires and you set the boolean back to false
or
you call a method that does some math based on the saved location values and the finger that is still on the screen. The math should be pretty easy, but I don't know what you actually want to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With