android - 了解Android PointerID。返回意外值

最近,我收到了我的应用程序的崩溃报告,在查看了堆栈跟踪之后,意识到我的多点触摸控件存在问题。

发生的事情是这样的:

我正在尝试仅记录4个手指的手指按下次数。不再。我希望4岁以上的人被有效地“忽略”。

因此,我正在做这样的事情:

@Override
public boolean onTouchEvent(MotionEvent event) {

    pointerCount = event.getPointerCount();

    if (pointerCount <= 4){

    actionMask = event.getActionMasked();
    pointerIndex = event.getActionIndex();      
    pointerID = event.getPointerId(pointerIndex);
    //etc.............


因此,如果四指以上的话,我在onTouch上不会执行任何操作。

这似乎可以正常工作,通常不会在手指5、6等上“起作用”。所以一切都很好。 (由于以下原因,我通常说“”).....

问题

但是,如果我说向下放6个手指,然后再抬起,最后一个放下的手指的指标为5。这并不是真正的问题,因为我没有在action_up或action_pointer_up中做任何事情。

但是,在action_pointer_down中,我有90%的时间获得了预期的行为,即放下的任何手指的ID仅在0到3之间。

但是,如果您将5个或更多手指放在屏幕上,然后一遍又一遍地快速点击屏幕,最终,一个ID将分配给4个或更多的action_pointer_down事件(我见过4、5、6和7)因此,当尝试将这些值放入xList和yList数组中时,它会崩溃并出现超出范围的异常。

这是一个问题,因为在action_pointer_down中,我将手指的x和y保存到我创建的两个数组中。 (我需要此信息来稍后执行一些操作)。这些数组的大小均为4(因此索引为0到3)。像这样:

case MotionEvent.ACTION_POINTER_DOWN:{

    try{                        
            if (isJumpPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
                 //Jump here
            }


            else if (isLeftPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
                 //Move left here
            }

            else if(isRightPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
                //Move right here
            }

                //****These lines randomly fail if the pointerID >=4
                xList[pointerID]=event.getX(pointerIndex);
                yList[pointerID]=event.getY(pointerIndex);

    }
    catch(Exception e){                         
        Log.v("Error","Oops, something's wrong");                   
    }

    break;

    }

}


为什么是这样?这是Multi-touch API中的错误还是我不了解的东西?在正常使用中,通常不会发生该错误,但是我可以自己触发该错误并由用户发现它,因此,我们将不胜感激。我希望任何放下手指的事件只能获得0-3的ID。除非我误会了一些东西。

最佳答案

不要依赖于连续的指针ID或根本不与当前触摸屏幕的指针数量直接相关的指针。 ID是一个标识符,不是识别多少手指向下或哪些手指向下的方式。

The documentation指出ID只是一个介于0和getPointerCount() - 1之间的值,并且该ID在特定手势中使用。因此,如果Android将您的快速点击解释为一个手势,则可以想象同一手指多次点击可能具有不同的ID。

对于您的特定情况,听起来Map<int, float>可能更适合将特定的指针映射到其X和Y坐标。使用地图肯定会解决您的越界异常。

例如:

Map<Integer, Float> xMap = new HashMap<>();
// ...

case MotionEvent.ACTION_POINTER_DOWN: 
    // ...

    xMap.put(pointerID, event.getX(pointerIndex);


您以后可以用xMap.get(2)检索ID为2的指针的值。

本文翻译自 https://stackoverflow.com/questions/27649865/

网站遵循 CC BY-SA 4.0 协议,转载或引用请注明出处。

标签 android multi-touch indexoutofboundsexception actionevent ontouch


相关文章:

java - 在方法中输入安全参数

android - 如何编码多点触控

android - AppBarLayout:如何removeOnOffsetChangedListener

android - IndexOutOfBoundsException setSpan(0 ... 1)结束超过0

iphone - attributedSubstringFromRange的出界问题

android - android mapview标记大小

android - 如何让我的应用程序使用android以不同的语言显示

android - 背景图像从左向右移动

android - Android:AndroidPlot中的触摸事件期间应用程序崩溃

android - 在我的应用上禁用多点触控[重复]