I'm using the following code for android to create a list of polygons for later redraw. The problem is that for some reason the pointer ID returned is 0, when one finger is held and another is pressed to the screen. However, when one or multiple fingers press the screen simultaneous the correct Id's are generated.
public boolean onTouchEvent(MotionEvent e) {
//Cycle through all pointer indexes
for(int i=0; i < e.getPointerCount(); i++){
int PointerId=e.getPointerId(i); //Get the pointer Id for that index.
int x= (int)e.getX(e.findPointerIndex(PointerId)); //Get the x coordinate for the current pointer id.
int y= (int)e.getY(e.findPointerIndex(PointerId)); //Get the y coordinate for the current pointer id.
//Handle Touch events.
switch(e.getActionMasked()){
case MotionEvent.ACTION_POINTER_DOWN: //Check for subsequent Pointer down events.
case MotionEvent.ACTION_DOWN:{ //Check for first finger down.
pntsU.put(PointerId,new Polygon(x,y,Color));//Create a new polygon finger down event, and associate with the Pointer Id.
Log.i("Pointer Id: ","" + PointerId); //Log the pointer id for testing.
break;
}
case MotionEvent.ACTION_MOVE:{ //A finger move event has occured.
pntsU.get(PointerId).Points.add(new Point(x,y));//Add a point to the Associated polygon.
break;
}
case MotionEvent.ACTION_POINTER_UP: //A finger has been lifted.
case MotionEvent.ACTION_UP:{
pntsCommited.add(pntsU.get(PointerId)); //Store the associated polygon in a permanent list.
break;
}
}
}
invalidate();
return true;
}
Edit: For anyone else who cares, or is having this problem, I have solved it. Here is my updated code.
public boolean onTouchEvent(MotionEvent e) {
int x,y;
int PointerId,PointerIndex;
//Handle Touch events.
switch(e.getActionMasked()){
case MotionEvent.ACTION_POINTER_DOWN: //Check for subsequent Pointer down events.
case MotionEvent.ACTION_DOWN:{ //Check for first finger down.
PointerIndex = (e.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
PointerId= e.getPointerId(PointerIndex);
x= (int) e.getX(PointerIndex);
y= (int) e.getY(PointerIndex);
pntsU.put(PointerId,new Polygon(x,y,Color)); //Create a new polygon finger down event, and associate with the Pointer Id.
break;
}
case MotionEvent.ACTION_MOVE:{ //A finger move event has occurred.
//Cycle through all pointer indexes
for(int i=0; i < e.getPointerCount(); i++){
PointerId=e.getPointerId(i); //Get the pointer Id for that index.
x= (int)e.getX(e.findPointerIndex(PointerId)); //Get the x coordinate for the current pointer id.
y= (int)e.getY(e.findPointerIndex(PointerId)); //Get the y coordinate for the current pointer id.
x=Math.max(x,0); //Enforce x and y boundaries.
x=Math.min(x,getWidth());
y=Math.max(y,0);
y=Math.min(y,getHeight());
pntsU.get(PointerId).Points.add(new Point(x,y)); //Add a point to the Associated polygon.
}
break;
}
case MotionEvent.ACTION_POINTER_UP: //A finger has been lifted.
case MotionEvent.ACTION_UP:{
PointerIndex = (e.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
PointerId= e.getPointerId(PointerIndex);
pntsCommited.add(pntsU.get(PointerId)); //Store the associated polygon in a permanent list.
break;
}
}
invalidate();
return true;
}
Notice that I have moved the for-loop code into the Action_Move section fixing the problem. I'm not exactly sure why this works, but my guess is that it probably has something to do with the fact that Action_Move event always returns a pointer Id of 0, and thus was causing the second click to return 0 under certain circumstances. Forcing the cycling of pointer indexes in the Action_Move will fix this problem and ensure that you get the correct pointer Id's.