Android Multitouch - Second Finger ACTION.MOVE Ignored
Nevermind this. I fixed it. The ACTION.MOVE event always gets zero as the pointerId for some strange reason. Because of this, you always have to recalculate the pointerId within the event as seen below:
case MotionEvent.ACTION_MOVE:
int pointerCount = event.getPointerCount();
for(int i = 0; i < pointerCount; ++i)
{
pointerIndex = i;
pointerId = event.getPointerId(pointerIndex);
Log.d("pointer id - move",Integer.toString(pointerId));
if(pointerId == 0)
{
fingerOneDown = 1;
fingerOneX = event.getX(pointerIndex);
fingerOneY = event.getY(pointerIndex);
}
if(pointerId == 1)
{
fingerTwoDown = 1;
fingerTwoX = event.getX(pointerIndex);
fingerTwoY = event.getY(pointerIndex);
}
}
break;
Nathan Tornquist
I am a full stack developer working in Chicago. I primarily develop for iOS and Node, but have a background in Ruby, Java, and C#. I dabble in hardware prototyping, and have a degree in Computer Engineering from Purdue. Outside of work, I enjoy playing the trumpet and reading novels.
Updated on June 07, 2022Comments
-
Nathan Tornquist almost 2 years
The following code is what I've been trying to use for multitouch. Finger one is set correctly and moves around when I drag my finger. Finger two shows up and disappears when I touch and release my finger, but it never moves around. Any idea what's wrong?
I have read developers blog I still do not understand what the issues are.
@Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction() & MotionEvent.ACTION_MASK; int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; int pointerId = event.getPointerId(pointerIndex); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: if (pointerId == 0) { fingerOneDown = 1; fingerOneX = event.getX(pointerIndex); fingerOneY = event.getY(pointerIndex); } if (pointerId == 1) { fingerTwoDown = 1; fingerTwoX = event.getX(pointerIndex); fingerTwoY = event.getY(pointerIndex); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: if (pointerId == 0) { fingerOneDown = 0; fingerOneX = event.getX(pointerIndex); fingerOneY = event.getY(pointerIndex); } if (pointerId == 1) { fingerTwoDown = 0; fingerTwoX = event.getX(pointerIndex); fingerTwoY = event.getY(pointerIndex); } break; case MotionEvent.ACTION_MOVE: if (pointerId == 0) { fingerOneDown = 1; fingerOneX = event.getX(pointerIndex); fingerOneY = event.getY(pointerIndex); } if (pointerId == 1) { fingerTwoDown = 1; fingerTwoX = event.getX(pointerIndex); fingerTwoY = event.getY(pointerIndex); } break; } return true; }
-
C.d. almost 11 yearsIs this a bug? I have the same strange behaviour. I searched in Google and some other people have this too.
-
Nathan Tornquist almost 11 yearsI don't know if it is a bug, but this is a documented concern and iterating through the pointerIds solves it. If anything, it could just be a strange design decision.
-
Pavel Horal about 10 yearsJust encountered this and I have to say it is pretty logical. POINTER DOWN/UP is a simple event and can be fired as separate events. MOVE is however related to every pointer. Separating pointer movement into different events would make things pretty complicated and maybe even impossible (distinguishing between multi-pointer swipe and single finger swipe while holding second pointer at one place). Thus action index does not make sense for MOVE and you need to check pointer movement manually via iteration (as you have shown) and stored history (to check which one has moved).
-
Zach about 7 yearsTo determine which pointer has moved, you can use MotionEvent.getHistoricalX(). Code from r3dux.org: if ( (int)event.getX(i) != (int)event.getHistoricalX(i,0) || (int)event.getY(i) != (int)event.getHistoricalY(i, 0) )