2

onTouchタッチをキャッチしてダブルタップをキャプチャする方法をACTION_UP使用していますGestureDetector。私の問題は、ダブルタップすると、タップしてからダブルタップしてからタップすることです。ダブルタップでタップなどをブロックする方法はありますか? 私はその動作が正しいことを論理的に知っているので、コメントする別の方法を見つけることをアドバイスする場合は、反対票を投じないでください。ありがとう!

4

3 に答える 3

3

britzlが言っていることよりも正確に言うと、GestureDetector何かがシングルタップ、ダブルタップ、長押しなどであるかどうかを判断する実際の作業を行います。 は、認識したものを示すSimpleGestureListenerために使用する単なる「リスナー」です。GestureDetector実装OnGestureListenerOnDoubleTapListenerて、常に false を返すだけです。のスニペットをチェックしてonTouchEvent(MotionEvent)くださいGestureDetector:

case MotionEvent.ACTION_DOWN:
        if (mDoubleTapListener != null) {
            boolean hadTapMessage = mHandler.hasMessages(TAP);
            if (hadTapMessage) mHandler.removeMessages(TAP);
            if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
                    isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
                // This is a second tap
                mIsDoubleTapping = true;
                // Give a callback with the first tap of the double-tap
                handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
                // Give a callback with down event of the double-tap
                handled |= mDoubleTapListener.onDoubleTapEvent(ev);
            } else {
                // This is a first tap
                mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
            }
        }

        mDownFocusX = mLastFocusX = focusX;
        mDownFocusY = mLastFocusY = focusY;
        if (mCurrentDownEvent != null) {
            mCurrentDownEvent.recycle();
        }
        mCurrentDownEvent = MotionEvent.obtain(ev);
        mAlwaysInTapRegion = true;
        mAlwaysInBiggerTapRegion = true;
        mStillDown = true;
        mInLongPress = false;
        mDeferConfirmSingleTap = false;

        if (mIsLongpressEnabled) {
            mHandler.removeMessages(LONG_PRESS);
            mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
                    + TAP_TIMEOUT + LONGPRESS_TIMEOUT);
        }
        mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
        handled |= mListener.onDown(ev);
        break;

次に、適切なリスナーを使用してを作成することにより、目的の結果を取得できます。GestureDetector

final View.OnTouchListener touch_listener = new View.OnTouchListener() {

            @Override public boolean onTouch(View view, MotionEvent event) {
                return _gesture_detector.onTouchEvent(event);
            }

            private final GestureDetector _gesture_detector = new GestureDetector(getContext()
                    , new GestureDetector.SimpleOnGestureListener() {

                @Override public boolean onSingleTapConfirmed(MotionEvent event) {
                    // TODO: implement single tap behavior
                    // NOTE: returning true indicates that the gesture was handled
                    return true;
                }

                @Override public boolean onDoubleTap(MotionEvent event) {
                    // TODO: implement double tap behavior
                    // NOTE: returning true indicates that the gesture was handled
                    return true;
                }
            });
        };

そしてそこから、これは動作OnTouchListenerが必要な に設定できますView

デフォルトGestureHandler( a Handler)を使用して機能します:

private class GestureHandler extends Handler {
    GestureHandler() {
        super();
    }

    GestureHandler(Handler handler) {
        super(handler.getLooper());
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case SHOW_PRESS:
            mListener.onShowPress(mCurrentDownEvent);
            break;

        case LONG_PRESS:
            dispatchLongPress();
            break;

        case TAP:
            // If the user's finger is still down, do not count it as a tap
            if (mDoubleTapListener != null) {
                if (!mStillDown) {
                    mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
                } else {
                    mDeferConfirmSingleTap = true;
                }
            }
            break;

        default:
            throw new RuntimeException("Unknown message " + msg); //never
        }
    }
}

mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);の行を思い出してくださいGestureDetector。有効なダブルタップ ジェスチャのタイムアウト期間だけ、タップの通知を遅らせます。if (hadTapMessage) mHandler.removeMessages(TAP);からの行はGestureDetector、有効なダブルタップでその通知を削除します。はGestureHandler遅延後にタップ通知を受信し、コールバックを使用して with に通知GestureListenermDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);ます。は、タップ通知の受信時にユーザーの指が下にある場合に、 ( によって処理される)GestureHandlerへのコールバックを遅らせます。MotionEvent.ACTION_UPGestureDetector

于 2014-01-30T18:45:35.097 に答える
0

britzl が提案することに加えて、ロジックを少し確認したい場合があります。

ダブルタップで複数になるとは思いません。あなたが言及したように、単に4つのイベントが発生するだけです。Gesture ライブラリは (私が思うに) 最良の選択ですが、次のことを考慮する必要があります。

  • Motionevent のタイムスタンプ (メソッドの 1 つ) を ACTION_UP に保存し、次のアクションと比較します。タイムアウトがあれば、タップかダブルタップかがわかります。

それがジェスチャーリスナーが行うことです

于 2013-05-21T21:50:13.797 に答える