1

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

发生的事情是这样的:

我正在尝试仅记录 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.............

因此,如果超过 4 个手指按下,我不会在 onTouch 中运行任何东西。

这似乎工作正常,它通常不会在手指 5、6 等上“起作用”。所以一切都很好。(我说“一般”是因为接下来的内容).....

问题

但是,如果我说 6 根手指向下,然后将它们抬起,最后一根手指向下的指针 ID 为 5。这并不是真正的问题,因为我在action_upaction_pointer_up中没有做任何事情。

然而,在action_pointer_down中,90% 的时间我会得到预期的行为,即任何手指放下的 ID 都在 0 到 3 之间。

但是,如果您将 5 个或更多手指放在屏幕上并一遍又一遍地快速点击屏幕,最终会为action_pointer_down事件分配一个 ID为 4 或更多(我见过 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;

    }

}

为什么是这样?这是多点触控 API 中的错误还是我不理解的问题。在正常使用中,该错误通常不会发生,但我可以自己轻松触发它并由用户发现,因此不胜感激。我希望任何手指按下事件都只会收到 0-3 的 ID。除非我误解了什么。

4

1 回答 1

1

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

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

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

例如:

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

case MotionEvent.ACTION_POINTER_DOWN: 
    // ...

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

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

于 2014-12-25T19:19:56.720 回答