在Android上获取当前手指位置



我正在开发一个应用程序,该应用程序需要将所有手指都放在Android的屏幕上。这并不复杂,我可以在几行代码中完成。

然而,android发送回调的方式并不是我所需要的。我做了很多测试,下面是我能找到的:

一旦他发送了手指位置,如果没有做出"大"动作,他将不会发送onTouch事件。

此外,当一根手指从屏幕上移开时(例如:有3根手指,其中一根被移开),如果剩余的手指中至少有一根在屏幕上移动,它似乎只发送下一个事件。

我正在对手指进行跟踪,并与对象进行匹配,为了正确地进行匹配,我需要一直知道所有手指的位置。如果即使手指没有移动,也无法"请求"手指的触摸事件,那么如何在没有回调事件的情况下访问当前手指位置?还有其他解决方案吗?

这是我的代码:

ArrayList<Vector3> fingerTips = new ArrayList<Vector3>();
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int points = event.getPointerCount();
        String out = "==========n";
        fingerTips.clear();
        for(int i = 0; i < points; i++){
            out += "tPoint "+i+"t("+event.getX(i)+", "+event.getY(i) + ")n";
            fingerTips.add( new Vector3(event.getX(i), event.getY(i)) );
        }
        Log.i(TAG, out);
        // Send touches to SurfaceView
        chwaziViewGL.onUpdateFingerTips(fingerTips);
        return true;
    }

我的问题是,在移除手指后,我没有收到一个具有所有手指位置的event。。。

经过大量的测试和日志记录,我发现这是真的(部分)。

无论何时移除屏幕上的手指,发送的NEXT事件都是ACTION_POINTER_UPACTION_UP,这意味着手指x不再接触屏幕。

由于移除手指后没有运动,所以最后发送的MotionEventUP,也包含移除的手指。

因此,为了解决这个问题,我检查动作是否为UP,在得到所有手指的循环中,我创建了一个if,检查那是否是从屏幕上删除的手指。如果是,我只是没有将其添加到数组中。

这是我的最终代码:

ArrayList<Vector3> fingerTips = new ArrayList<Vector3>();
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int points = event.getPointerCount();
        // Check if it's an event that a finger
        // was removed, if so, set removedPoint
        int removedPoint = -1;
        final int action = event.getAction() & MotionEvent.ACTION_MASK;
        if(action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP)
            removedPoint = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;

        String out = "==========n";
        fingerTips.clear();
        for(int i = 0; i < points; i++){
            // Find out pointer ID
            int pointerID = event.getPointerId(i);
            if(pointerID == MotionEvent.INVALID_POINTER_ID){
                out += "tPoint "+pointerID+" INVALIDn";
                continue;
            }
            // Check if it's the removed finger
            if(removedPoint == i){
                out += "tPoint "+pointerID+" REMOVEDn";
                continue;
            }
            out += "tPoint "+pointerID+"t("+event.getX(i)+", "+event.getY(i) + ")n";
            fingerTips.add( new Vector3(event.getX(i), event.getY(i), pointerID) );
        }
        Log.i(TAG, out);
        // Send touches to SurfaceView
        chwaziViewGL.onUpdateFingerTips(fingerTips);
        return true;
    }

对不起,你的代码花了我很多钱-(几天后,我终于发现了问题,然后我就疯了。这个代码

final int action = event.getAction() & MotionEvent.ACTION_MASK;
if(action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP)
        removedPoint = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;

根本不可能成功!!!

为什么?因为如果您屏蔽来自getAction()的值,它只是操作的一个普通整数值。当你试图使用这个简单的值并用一些东西再次掩盖它时,它根本没有意义!

更正是在屏蔽后的几秒钟内再次使用event.getAction():

removedPoint = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;

发现这个真是一场噩梦。但无论如何,我认为你只是想要最好的并帮助他人:-))没关系。

最新更新