Указатель индекса вне диапазона Android мультитач - PullRequest
29 голосов
/ 03 августа 2011

У меня есть исключение события касания, которое вызывает сбой моей игры на планшетах (или, точнее, в сотах) ... Моя игра отлично работает на моем телефоне, и я не слышал, чтобы это происходило с кем-то, кто под управлением Android 3.0 или выше. Вот соответствующая информация журнала ...

E/AndroidRuntime(26487): java.lang.IllegalArgumentException: pointerIndex out of range
E/AndroidRuntime(26487):    at android.view.MotionEvent.nativeGetAxisValue(Native Method)
E/AndroidRuntime(26487):    at android.view.MotionEvent.getX(MotionEvent.java:1549)
E/AndroidRuntime(26487):    at kieran.android.asteroids.GameUI.onTouchEvent(GameUI.java:665)
E/AndroidRuntime(26487):    at android.view.View.dispatchTouchEvent(View.java:4616)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1560)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1291)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1560)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1291)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1560)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1291)

... А вот код, который его вызывает. Кажется, хорошо для меня, но, может быть, есть ошибка в сотах, которая еще не исправлена? Строка с номером 665 из журнала выше соответствует строке float x = event.getX(id);. Возможно, это как-то связано с тем, как я получаю переменную which? Но на телефонах / 2.3 и ниже работает нормально ...

int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;

if(actionCode == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP) {
    int which = action >> MotionEvent.ACTION_POINTER_ID_SHIFT;
    int id = event.getPointerId(which);
    float x = event.getX(id);
    float y = event.getY(id);

Буду очень признателен за любую помощь / идеи, поскольку я пытаюсь сделать свою игру доступной для пользователей планшетов. Спасибо.

Ответы [ 5 ]

49 голосов
/ 07 сентября 2011

Моя проблема заключалась в том, что он фактически вызывал event.getX (1), когда фактически не было двух идентификаторов. Поэтому я убедился, что было два идентификатора с event.getPointerCount ()> = 2, и теперь он работает. Может быть, тебе повезет!

7 голосов
/ 03 августа 2011

Если вам не хватает нескольких вещей, вам нужно применить маску к указателю, иначе у вас нет технического доступа к идентификатору пальца, который вы считаете

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);
2 голосов
/ 21 октября 2012

У меня также есть эта ошибка, но ни одно из решений до даты моей публикации работы. Единственное временное псевдо-исправление, которое мне подходит, это использовать try-catch против IllegalArgumentException .

Согласно Android выпуск 18990 , он связан с ScaleGestureDetector, и исправление было зафиксировано несколько дней назад.

1 голос
/ 21 января 2013

Исходная публикация использует идентификатор указателя, когда getX и getY используют индекс указателя.

Кажется, что работает, когда вы используете идентификатор для одного касания, потому что идентификатор и индекс оба равны 0.Если вы используете мультитач, то все будет плохо, потому что индексы могут измениться.

Пример:

Нажмите 1 вниз.
Нажмите 1, индекс состояния = 0,ID = 0

Коснитесь 2 вниз.
Коснитесь 1 Индекс состояния = 0.Идентификатор = 0
Состояние касания 2 Индекс = 1. Идентификатор = 1

Отпуск 1 Сенсор.
Состояние касания 2 Индекс = 0 ,ID = 1

Попробуйте следующий код:

final int action = e.getAction();       
final int pointerIndex =(action & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;      
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
1 голос
/ 05 сентября 2011

Просто измените getPointerId() на findPointerIndex(). Возможно изменить geAction() на getActionMasked().

Надеюсь, это поможет!

...