public bool OnTouch(View v, MotionEvent @event) { lock (this) { int action = @event.GetAction() & MotionEvent.ACTION_MASK; int pointerIndex = (@event.GetAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; int pointerCount = @event.GetPointerCount(); TouchEvent touchEvent; for (int i = 0; i < MAX_TOUCHPOINTS; i++) { if (i >= pointerCount) { isTouched[i] = false; id[i] = -1; continue; } int pointerId = @event.GetPointerId(i); if (@event.GetAction() != MotionEvent.ACTION_MOVE && i != pointerIndex) { // if it's an up/down/cancel/out event, mask the id to see if we should process it for this touch // point continue; } switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: touchEvent = touchEventPool.newObject(); touchEvent.type = TouchEvent.TOUCH_DOWN; touchEvent.pointer = pointerId; touchEvent.x = touchX[i] = (int)(@event.GetX(i) * scaleX); touchEvent.y = touchY[i] = (int)(@event.GetY(i) * scaleY); isTouched[i] = true; id[i] = pointerId; touchEventsBuffer.Add(touchEvent); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: touchEvent = touchEventPool.newObject(); touchEvent.type = TouchEvent.TOUCH_UP; touchEvent.pointer = pointerId; touchEvent.x = touchX[i] = (int)(@event.GetX(i) * scaleX); touchEvent.y = touchY[i] = (int)(@event.GetY(i) * scaleY); isTouched[i] = false; id[i] = -1; touchEventsBuffer.Add(touchEvent); break; case MotionEvent.ACTION_MOVE: touchEvent = touchEventPool.newObject(); touchEvent.type = TouchEvent.TOUCH_DRAGGED; touchEvent.pointer = pointerId; touchEvent.x = touchX[i] = (int)(@event.GetX(i) * scaleX); touchEvent.y = touchY[i] = (int)(@event.GetY(i) * scaleY); isTouched[i] = true; id[i] = pointerId; touchEventsBuffer.Add(touchEvent); break; } } return(true); } }