1

ほとんどすべてのジェスチャーを消費する必要がある View を作成しています。これを行うために、ScaleGestureDetector と GestureDetector を作成しました。また、リスナー クラスを 1 つ作成し、必要なすべてのインターフェイスを実装できることに気付きました。だから私はしました。OnGestureListener と OnDoubleTapListener は同じクラスに由来するため、これは完全に理にかなっていますが、次のようになります。

  • ScaleGestureDetector は独自のリスナー クラスを期待しますか?
  • 同じクラスに満足している場合、独自のオブジェクトを期待しますか?
  • 逆に、両方の検出器で同じリスナーを使用する必要がありますか?

実験により、次のことが確認されました。

  • 確かに 1 つのリスナー クラスを使用できますが、
  • ScaleGestureDetector と GestureDetector は、同じイベントを消費すると、お互いに迷惑をかける可能性があります。でも
  • 通常の検出器を実行する前に、常にスケール検出器を最初に呼び出してから、その isInProgress() メソッドをチェックすることで、この相互のイライラを防ぐことができるようです。

    public boolean onTouchEvent(MotionEvent event) {
    //let the ScaleGestureDetector try first
        mScaleDetector.onTouchEvent(event);
    //if isInProgress() returns true then it's consuming the event
        if(mScaleDetector.isInProgress()) return true;
    //if isInProgress() returns false it isn't consuming the event
    //it's therefore safe to pass it to the regular detector
        mPrimaryDetector.onTouchEvent(event);
        return true;
    }
    
4

3 に答える 3

3

MotionEvent がマルチタッチ イベントかどうかを判断するには、単純にMotionEvent.getPointerCount() > 1. したがって、次のコードはうまくいくと思います。

public boolean onTouchEvent(MotionEvent event) {
    if (event.getPointerCount() > 1) {
        mScaleDetector.onTouchEvent(event);
    } else {
        mDetector.onTouchEvent(event);
    }
    return true;
}
于 2013-05-29T01:51:25.967 に答える
2

ScaleGestureDetector と GestureDetector は、同じイベントを消費すると、お互いに迷惑をかける可能性があります。ただし、常にスケール検出器を最初に呼び出してから、通常の検出器を実行する前にその isInProgress() メソッドをチェックすることで、この相互のイライラを防ぐことができるようです

個人的には、両方に同じタッチ イベントを処理させても問題は見つかりませんでした。

アンドロイドGestureDetectorには、ブール値を取るコンストラクターignoreMultiTouchがあります。に設定ignoreMultiTouchするtrueと、GestureDetectorタッチ イベント処理でマルチタッチ イベントが無視されるようになります。(ターゲット API レベルが >= Froyo の場合、Android は実際に に設定ignoreMultiTouchするため、おそらく明示的に設定する必要はありません。)true

のみを呼び出すとmPrimaryDetector.onTouchEvent(event)、 whenmScaleDetector.isInProgress()が false を返すと、長押しイベントが誤って取得されます。その理由は、マルチタッチ ジェスチャと競合しないようにするためにGestureDetector、次のコードが含まれているためです。onTouchEvent(MotionEvent ev)

case MotionEvent.ACTION_POINTER_DOWN:
  if (mIgnoreMultitouch) {
    // Multitouch event - abort.
    cancel();
  }
  break;

cancel()それが言うことを行い、シングルタッチジェスチャをキャンセルします。(本当に興味がある場合は、そのGestureDetector コードを自分で確認できます。実際にはハンドラーを使用してメッセージを送信/削除します)。

これが、私と同じ問題を抱えていた人の助けになることを願っています。

于 2012-01-03T23:04:00.550 に答える
0

これは私にとってうまくいきます:

@Override
public boolean onTouchEvent(MotionEvent event) {
    m_sGestureDetector.onTouchEvent(event);
    m_GestureDetector.onTouchEvent(event);
    return true;
}
于 2012-02-01T18:19:51.470 に答える