4
public class GameActivity extends Activity {
    private static final String TAG = "GameActivity";

   . . .

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "+ onTouchEvent(event:" + event + ")");
        Log.d(TAG, "- onTouchEvent()");
        return super.onTouchEvent(event);
    }

    . . .
}


public class GameView extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "GameView";

    . . .

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "+ onTouchEvent(event:" + event + ")");
        gestureDetector.onTouchEvent(event);
        Log.d(TAG, "- onTouchEvent()");
        return super.onTouchEvent(event);
    }

    private SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() {
        private static final String TAG = "GestureListener";

        @Override
        public boolean onSingleTapConfirmed(MotionEvent event) {
            Log.d(TAG, "+ onSingleTapConfirmed(event:" + event + ")");
            singleTapDetected = true;
            Log.d(TAG, "- onSingleTapConfirmed()");
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent event) {
            Log.d(TAG, "+ onDoubleTap(event:" + event + ")");
            doubleTapDetected = true;
            Log.d(TAG, "- onDoubleTap()");
            return true;
        }
    };

    private GestureDetector gestureDetector = new GestureDetector(getContext(), gestureListener);

    . . .
}

AVDで実行し、SurfaceView(GameView)をシングルクリックしました。
LogCatログによると:

03-11 14:19:51.171: D/GameView(4839): + onTouchEvent(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=1071.0, y[0]=437.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=27223172, downTime=27223172, deviceId=0, source=0x1002 })
03-11 14:19:51.171: D/GameView(4839): - onTouchEvent()
03-11 14:19:51.171: D/GameActivity(4839): + onTouchEvent(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=1071.0, y[0]=437.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=27223172, downTime=27223172, deviceId=0, source=0x1002 })
03-11 14:19:51.171: D/GameActivity(4839): - onTouchEvent()
03-11 14:19:51.299: D/GameActivity(4839): + onTouchEvent(event:MotionEvent { action=ACTION_UP, id[0]=0, x[0]=1071.0, y[0]=437.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=27223303, downTime=27223172, deviceId=0, source=0x1002 })
03-11 14:19:51.299: D/GameActivity(4839): - onTouchEvent()

いくつかの質問があります:

  1. なぜSimpleOnGestureListener呼ばれなかったのですか?(onTouchEvent()呼び出され、おそらくラインgestureDetector.onTouchEvent(event);が実行されたにもかかわらず)

  2. GameActivityonTouchEvent()ACTION_DOWNACTION_UPを取得するのに、GameViewはACTION_DOWNonTouchEvent()しか取得しないのはなぜですか?

私が試したいくつかのこと

  • 上記と同じコードを使用しGestureDetectorてクラスにを実装しましたが、期待どおりに機能し、GameActivityonSingleTapConfirmed()

  • GameViewでは、プライベートメンバーの代わりに、プライベートSimpleOnGestureListenerを作成し、class GestureListener extends SimpleOnGestureListenerそれを使用してを構築しましたGestureDetector。説明したのと同じ動作が見られますが、リスナーへの呼び出しはありません。

4

1 に答える 1

8

コードを Android ソース コード、GestureDetector クラスにデバッグしました。そして、これはなぜSimpleOnGestureListener呼び出されなかったのかを説明しています:

  • ACTION_DOWN が受信され、GestureDetector メッセージ ハンドラーへの内部 TAP メッセージが生成されます。
  • Handler はonSingleTapConfirmed()、イベントがまだ停止していない場合にのみリスナーを呼び出します( !mStillDown)
  • ACTION_UP イベントが受信されなかったため、イベントはまだダウンしています。

ご覧のとおり、2 つの質問は関連しています。ACTION_UP が発行されない理由がわかれば、問題を解決できます。

編集

これで答えが完成しました。今は機能しています。

  • SurfaceView のクラスが View であるため、super.onTouchEvent()GameView での呼び出しは を返し、 を返します。そのため、 ACTION_UP は呼び出されませんfalsesuperfalse
  • GameActivityの への呼び出しは をsuper.onTouchEvent()返しますtrue。そのため、GameActivity で ACTION_UP が発行されます。

注: 設定すると GameView.setclickable(true) super.onTouchEvent() が返さ trueれます。それも許容できる解決策です

今私のGameViewコードは次のとおりです。

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d(TAG, "+ onTouchEvent(event:" + event + ")");
    gestureDetector.onTouchEvent(event);
    Log.d(TAG, "- onTouchEvent()");
    return true;
}

現在の LogCat ログは次のとおりです。

03-11 16:32:06.629: D/GameView(5316): + onTouchEvent(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=977.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158623, downTime=35158623, deviceId=0, source=0x1002 })
03-11 16:32:06.629: D/GameView(5316): - onTouchEvent()
03-11 16:32:06.641: D/GameView(5316): + onTouchEvent(event:MotionEvent { action=ACTION_MOVE, id[0]=0, x[0]=978.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158623, downTime=35158623, deviceId=0, source=0x1002 })
03-11 16:32:06.641: D/GameView(5316): - onTouchEvent()
03-11 16:32:06.772: D/GameView(5316): + onTouchEvent(event:MotionEvent { action=ACTION_UP, id[0]=0, x[0]=978.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158772, downTime=35158623, deviceId=0, source=0x1002 })
03-11 16:32:06.772: D/GameView(5316): - onTouchEvent()
03-11 16:32:06.931: D/GestureListener(5316): + onSingleTapConfirmed(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=977.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158623, downTime=35158623, deviceId=0, source=0x1002 })
03-11 16:32:06.931: D/GestureListener(5316): - onSingleTapConfirmed()
于 2013-03-11T16:38:01.850 に答える