Android MotionEvent Confusion Pointer Index

I have a problem with my Android app that needs touch tracking events (tracking when / where the finger goes down, moves, up, etc.). I have to use the functions event.getX() and event.getY() to get the current touch coordinates.

So, from what I learned in the last few months:

  • MotionEvent.ACTION_DOWN tracks the first click
  • MotionEvent.ACTION_POINTER_DOWN tracks subsequent downwards clicks.
  • MotionEvent.ACTION_UP tracks the last touch
  • MotionEvent.ACTION_POINTER_UP tracks the touch that rises
  • MotionEvent.ACTION_MOVE keeps track of any touch movement.

In my application, I am faced with a serious problem when my first touch rises. Suppose I have five fingers touching my device (lets call these Touch 0, 1, 2, 3, 4). Now, when I raise Touch 0, MotionEvent.ACTION_POINTER_UP is the action I get. Quite understandable; I understand it. However, now these two things will happen:

  • Move something from Touches 1-4: get an IllegalArgumentException , indicating that pointerIndex is out of range.
  • Lift something from the hip joint 1-4: splash out the information for another touch ( event.getX() and event.getY() will give me other information about the fingers)

I’m kind of in my mind how to properly track this information. Any tips on how to properly track information or move touch pointers?

I presented a general layout of what my code is, but I feel like I'm not doing anything unusual (and I'm sure that it is close to the code example on 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 } 
+5
source share
1 answer

Well, after thinking about this for the night, I started working on this before calling MotionEvent.getX() and MotionEvent.getY() :

 public int getAdjustment(int ptr_idx) { int adjust = 0; for (int i = 0; i < event.getPointerCount(); i++) { // Get Actual Pointer Index of touch int adjustedPointerIndex = event.getPointerId(i); // If we've found the current touch pointer index AND // the pointer index doesn't equal the sequential event's // pointers if ((adjustPointerIndex == ptr_idx) && (i != adjustPointerIndex)) { adjust = (adjustPointerIndex - i); break; } } return adjust; } // Example Function using getAdjustment(int ptr_idx) public void handleActionPointerUp(MotionEvent event, int ptr_idx) { int adjustment = ptr_idx - getAdjustment(ptr_idx); handleInformation(event.getX(adjustment), event.getY(adjustment)); } 

Explanation of the for loop statement:

Basically, let's say we have 4 touches (Touch 0, 1, 2, 3). Now we raised Touch 0, and now we have Touch 1, 2, 3. Android will see these strokes as 0, 1, 2 and the actual index indices as 1, 2, 3. To get the right setting, I repeat the MotionEvent pointers (this 0, 1, 2 right now in the for loop).

Now, if for some reason Touch 0 or any touch between them is taken out, we must configure the index of the pointer as getX() and getY() does not understand the index of the actual touch pointer. It only accepts indexes 0, 1, 2, although we have indexes of pointers 1, 2, 3. Thus, if we reach the correct index of the touch pointer, but the touch index of MotionEvent does not match the correct pointer of the pointer of the pointer, we configure it by adjust = adjustPointerIndex-i .

After that, simply subtract it from the current ptr_idx , which we are analyzing, and get a value that getX() and getY() can understand without IllegalArgumentException for the pointerIndex parameter out of range.

It will be explained in more detail if that doesn't make sense, and if anyone has a more elegant solution, let me know because I'm sure this is not a great way to handle this. I would rather tag someone else as an approved answer.

0
source

All Articles