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);
    }
}

edit2:完全なリストリンク

いくつかのログを調べると、たとえば次のことがわかりました。タッチフィンガー#1タッチフィンガー#2タッチフィンガー#3リリースフィンガー#3リリースフィンガー#2リリースフィンガー#1

大丈夫ですがやっています:

タッチフィンガー#1タッチフィンガー#2タッチフィンガー#3リリースフィンガー#1リリースフィンガー#2リリースフィンガー#3

最後のタイマーをリークします。私は間違いなくIDとインデックスをいじっていると思います。

4

1 に答える 1

1

などの使用から判断すると、ポインターidではなく、ポインターindexgetX(id)であると推測しています。ポインター インデックスは、タッチ イベント間で持続することが保証されていないため、後のイベントで使用するときに同じタイマーが見つからない場合があります。id

ポインター ID を使用して、どれがどれであるかを追跡する必要があります。getPointerId()は、インデックスごとにそれを提供します。

まだ読んでいない場合は、Android ブログの Making Sense of Multitouchを読むことを強くお勧めします。

于 2013-02-14T21:08:26.997 に答える