1

我正在开发一个需要将所有手指都放在 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;
    }
4

2 回答 2

1

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

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

每当您在屏幕上移开手指时,发送的 NEXT 事件是ACTION_POINTER_UPor ACTION_UP,表示手指x不再触摸屏幕。

由于移除手指后没有任何动作,因此最后MotionEvent发送的是UP, 也包含移除的手指。

所以,为了解决这个问题,我检查了动作是否是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+" INVALID\n";
                continue;
            }

            // Check if it's the removed finger
            if(removedPoint == i){
                out += "\tPoint "+pointerID+" REMOVED\n";
                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;
    }
于 2013-07-30T18:14:07.557 回答
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;

不可能工作!

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

更正是在秒掩码中再次使用 event.getAction() :

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

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

于 2016-03-09T21:11:02.583 回答