【问题标题】:pointerIndex out of range Android multitouchpointerIndex 超出范围 Android 多点触控
【发布时间】:2011-10-18 15:46:37
【问题描述】:

我有一个触摸事件异常导致我的游戏在平板电脑(或者更具体地说,蜂窝)上崩溃...我的游戏在我的手机上运行良好,我没有听说过这种情况发生在任何人身上运行 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);

任何帮助/想法都将不胜感激,因为我正努力让我的游戏也可供平板电脑用户使用。谢谢。

【问题讨论】:

  • 是的,我在 HoneyComb 上也遇到了完全相同的问题,只有我的迷你钢琴。在手机上它只是表现正常。

标签: java android exception multi-touch


【解决方案1】:

getXgetY使用指针索引时,原贴使用指针id

当您将 ID 用于单点触控时,它似乎可以工作,因为 id 和索引都是 0。如果您使用多点触控,它会变得混乱,因为索引可以改变。

例子:

  • Touch 1 Down.
    Touch 1 State Index=0。 ID=0

  • Touch 2 Down。
    Touch 1 State Index=0。 ID=0
    Touch 2 状态 索引=1。 ID=1

  • Touch 1 释放。
    Touch 2 状态 Index=0。 ID=1

试试下面的代码:

int action = event.getAction();     
int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                   >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;       
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);

【讨论】:

  • 感谢这个答案,我发现有pointerIndexpointerIdgetXgetY的参数是前者。这是我长期以来一直忽略的。
【解决方案2】:

对于那些仍在寻找答案的人,请注意,当您使用任何带有 ZoomingScalingViewPager 时,也可能发生这种情况里面的图像等特征。那么你也有可能得到这个异常。

解决方案

扩展现有的 ViewPager 并用 try catch 覆盖这些方法。

@Override
public boolean onTouchEvent(MotionEvent ev) {
    try {
        return super.onTouchEvent(ev);
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    }
    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    try {
        return super.onInterceptTouchEvent(ev);
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    }
    return false;
}

【讨论】:

  • 你太棒了!这正是我的问题。
【解决方案3】:

我也遇到了这个错误,但在我发布工作日期之前没有任何解决方案。唯一对我有用的临时伪修复是对 IllegalArgumentException 使用 try-catch

根据AndroidIssue 18990,它与ScaleGestureDetector有关,几天前已提交修复。

【讨论】:

  • 完美解决方案
  • 我也使用 ScaleGestureDetector。但即使修复了这个错误,我们如何将这个解决方案反向移植到我们的构建中?
【解决方案4】:

我的问题是它实际上是调用 event.getX(1) 而实际上并没有两个 id。所以我确保有两个带有 event.getPointerCount() >= 2 的 id,它现在可以工作了。也许你也会有同样的运气!

【讨论】:

  • 你太棒了!这正是我的问题。我仍然不确定为什么我在手机上没有这个问题,但现在这已经解决了我的强制关闭问题。非常感谢!
  • 这是最好的解决方案!使用 David 和 Chris 建议的指针索引计算将防止三星 Note 2 上的放大和缩小
  • 运气不好,我在 onInterceptTouchEvent 中应用了 ev.getPointerCount() > 10 但它仍然崩溃
【解决方案5】:

只需将您的 getPointerId() 更改为 findPointerIndex()。也许将geAction() 更改为getActionMasked()

希望对你有帮助!

【讨论】:

  • 该死的也不要继续下去了...我对此寄予厚望。很难相信我还没有找到解决这个问题的方法,我不可能是唯一一个遇到这个问题的人。我已经尝试了很多东西......
  • iam 使用 findPointerIndex() getActionMasked() 但在多点触控中仍然崩溃。
【解决方案6】:

您缺少一些东西,您需要将掩码应用于指针,否则因为从技术上讲,您无法访问您认为自己是手指的 ID

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);

【讨论】:

  • 嗯...我明白你的意思。尽管更改后我仍然遇到相同的错误。错误来自 getX() 方法。我在传递给该函数之前记录了指针索引,它通常只是一个正数 1、2 或 3 等...,具体取决于它是哪个指针。还有其他想法吗?
  • 你现在在使用 event.getX(pointerIndex) 吗? getY 可能正在做同样的事情,只是在代码中没有走那么远。触摸屏幕时会崩溃吗?如果是这样,需要多少次触摸才能打破它
  • 这个代码在哪里被调用?它只是在 onTouch 之内吗?
  • 是的,我现在正在使用 event.getX(pointerIndex),是的,我很肯定 getY() 会做同样的事情,但它显然在那之前就崩溃了。打破它需要 2 次触摸,我放下一个指针,然后放下第二个指针,然后将第一个指针抬起,它就崩溃了。是的,就在 onTouchEvent() 中。我不太明白,因为它适用于我的手机,但不适用于我的平板电脑。
  • 在调试中运行并查看在崩溃前返回的指针索引和指针ID的值
猜你喜欢
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 2023-03-27
  • 2019-04-16
  • 2021-05-20
  • 2014-02-08
  • 2012-08-11
相关资源
最近更新 更多