I have a problem with my Android app that requires touch tracking events (tracking when/where finger goes down, move, up, etc). I have to use event.getX()
and event.getY()
functions to get the current touch's coordinates.
So from what I've learned in the past few months:
MotionEvent.ACTION_DOWN
tracks the first touch downMotionEvent.ACTION_POINTER_DOWN
tracks subsequent touches downMotionEvent.ACTION_UP
tracks the last touch upMotionEvent.ACTION_POINTER_UP
tracks touch that goes upMotionEvent.ACTION_MOVE
tracks any touch movement
In my app, I'm encountering a significant problem when my first touch goes up. Lets say I have five fingers touching my device (lets call these Touch 0, 1, 2, 3, 4). Now, when I lift up Touch 0, MotionEvent.ACTION_POINTER_UP
is the action I get. Totally understandable; I get this. However, now these two things will happen:
- Move anything from Touches 1-4: Get an
IllegalArgumentException
telling me the pointerIndex is out of range - Lift up anything from Touches 1-4: Spits back information for a different touch (
event.getX()
andevent.getY()
will give me a different finger information)
I'm kind of at my wit's end on how to properly track this information. Any clues on how to properly track the information or offset the touch pointers?
I provided the general layout of what my code is but I feel like I'm not doing anything out of the ordinary (and I'm sure it is close to the example code on the Android examples?):
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getActionMasked();
int ptr_idx = event.getPointerId(event.getActionIndex());
try {
switch (action) {
case MotionEvent.ACTION_MOVE:
handleActionPointerMove(event);
break;
// Order of touch downs doesn't matter to us
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
handleActionPointerDown(event, ptr_idx);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
handleActionPointerUp(event, ptr_idx);
break;
}
}
catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
}
return true;
}
}
public void handleActionPointerMove(MotionEvent event) {
for (int i = 0; i < event.getPointerCount(); i++) {
handleInformation(event.getX(i), event.getY(i));
}
}
public void handleActionPointerDown(MotionEvent event, int ptr_idx) {
handleInformation(event.getX(ptr_idx), event.getY(ptr_idx));
}
public void handleActionPointerUp(MotionEvent event, int ptr_idx) {
handleInformation(event.getX(ptr_idx), event.getY(ptr_idx));
}
public void handleInformation(int x, int y) {
// Figures out what x+y means to us (are we in a certain box within the app? outside in clear zones? etc
}