3

在我的应用程序中,我试图让粒子从可能的多个触摸位置发出。

我有一个用于存储点和相关计时器的类:

private static class Touch
{
    public Timer timer = new Timer();
    public vec position = new vec();
}

在 onTouchEvent 中,在 MotionEvent.ACTION_POINTER_DOWN 的情况下,我会实例化一个新的 Touch:

Touch t = new Touch();
t.position = new vec(event.getX(id), event.getY(id));
t.timer.scheduleAtFixedRate(new TimeredTouchTask(t.position, id), 0, SHOOTING_INTERVAL);

并将其存储在地图中,使用触摸 ID 作为键。

如果 MotionEvent.ACTION_POINTER_UP 被触发,我会通过在计时器上调用 cancel() 并将其从地图中移除来移除触摸。

最后,如果事件是 MotionEvent.ACTION_MOVE 类型,我只需迭代地图内的所有 Touch 实例并更新矢量坐标。

这可行,但有时定时器不会被正确删除,有时它们会保持活动状态,有时它们会继续实际拍摄粒子,即使我停止触摸屏幕也是如此。

我怎样才能使这段代码更健壮,以便它始终正确运行?

edit1:ACTION_POINTER_UP 的代码

我称这个方法

private void removeTouch(int id)
{
    Touch t = _touch.get(id);

    if(t != null)
    {
        if(t.timer != null)
        {
            t.timer.cancel();
            t.timer = null;
        }

        t = null;
        _touch.remove(id);
    }
}

编辑2:完整列表链接

通过检查一些日志,我发现例如:触摸手指#1 触摸手指#2 触摸手指#3 释放手指#3 释放手指#2 释放手指#1

没关系,但这样做:

触摸手指#1 触摸手指#2 触摸手指#3 释放手指#1 释放手指#2 释放手指#3

泄漏最后一个计时器。我想我肯定会弄乱 id 和索引。

4

1 回答 1

1

从您对getX(id), 等的使用来看,我猜id是指针index,而不是指针id。指针索引不能保证在触摸事件中保持持久,因此当您将它用于以后的事件时,您可能找不到相同的计时器。

您应该使用指针 id 来跟踪哪个是哪个。getPointerId()将为您提供每个索引的信息。

如果您还没有阅读,我强烈建议您阅读Android 博客上的Make Sense of Multitouch 。

于 2013-02-14T21:08:26.997 回答