タッチ、ジェスチャー

(ブログ記事の一覧は「こちら」)

画面のタッチや移動の検出や、スクロールやダブルタップなどのジェスチャーの検出を行う方法について学びましょう。

ここで学ぶこと

例題1

作成するもの

タッチイベントを取得するサンプルを作成します。

レイアウト

  • ImageView(課題1で使用します)

プログラム

MainActivity 内(のonCreate関数の外)にカーソルを合わせて、メニューの [Code] - [Override Methods...] から onTouchEvent を選択します。
以下はタッチの状態を検出したプログラムを追加したサンプルです。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        // タッチ開始
        case MotionEvent.ACTION_DOWN:
            break;
        // 移動中
        case MotionEvent.ACTION_MOVE:
            break;
        // タッチ終了
        case MotionEvent.ACTION_UP:
            break;
        // キャンセル
        case MotionEvent.ACTION_CANCEL:
            break;
    }

    // 座標を取得
    Log.v(TAG, "onTouchEvent: " + event.getX() + " " + event.getY());

    return super.onTouchEvent(event);
}

実行、確認

タッチした画面の座標の値が Logcat に出力されることで、タッチイベントが検出できていることを確認してください。

例題2

作成するもの

ジェスチャーイベントを取得するサンプルを作成します。

レイアウト

  • ImageView(課題2で使用します)

プログラム

まずはジェスチャーに必要な GestureDetectorクラスを定義してインスタンス(mGestureDetector)を生成します。
先ほどのタッチイベントで追加した onTouchEventメソッドに mGestureDetector の onTouchEventメソッドも呼ぶことによって、ジェスチャーイベントを取得することができます。

private static final String TAG = MainActivity.class.getSimpleName();

private GestureDetector mGestureDetector;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
        // 後でここにメソッドを追加する
    });
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    // これを追加することが必要
    mGestureDetector.onTouchEvent(event);

    (省略)

    return super.onTouchEvent(event);
}

onCreate関数内で mGestureDetector を生成するとき、SimpleOnGestureListener を選ぶことによって、基本的なジェスチャーイベント(OnGestureListener)に加え、ダブルタップのイベント(OnDoubleTapListener)も取得することができます。

mGestureDetector を生成した { } 内にカーソルを合わせて、メニューの [Code] - [Override Methods...] から 追加したいメソッドを選択します。
以下はメソッドを追加したプログラムのサンプルです。

   mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
        // ダウン
        @Override
        public boolean onDown(MotionEvent e) {
            Log.v(TAG, "onDown: " + e.getX() + " " + e.getY());
            return super.onDown(e);
        }

        // プレス
        @Override
        public void onShowPress(MotionEvent e) {
            super.onShowPress(e);
            Log.v(TAG, "onShowPress: " + e.getX() + " " + e.getY());
        }

        // アップ
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            Log.v(TAG, "onSingleTapUp: " + e.getX() + " " + e.getY());
            return super.onSingleTapUp(e);
        }

        // 長押し
        @Override
        public void onLongPress(MotionEvent e) {
            super.onLongPress(e);
            Log.v(TAG, "onLongPress: " + e.getX() + " " + e.getY());
        }

        // スクロール
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.v(TAG, "onScroll: " + e1.getX() + " " + e2.getY() + " " + distanceX + " " + distanceY);
            return super.onScroll(e1, e2, distanceX, distanceY);
        }

        // フリック
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            Log.v(TAG, "onFling: " + e1.getX() + " " + e2.getY() + " " + velocityX + " " + velocityY);
            return super.onFling(e1, e2, velocityX, velocityY);
        }

        // ダブルタップ
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.v(TAG, "onDoubleTap: " + e.getX() + " " + e.getY());
            return super.onDoubleTap(e);
        }

        // ダブルタップ中にタッチイベント
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            Log.v(TAG, "onDoubleTapEvent: " + e.getX() + " " + e.getY());
            return super.onDoubleTapEvent(e);
        }

        // シングルタップ
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.v(TAG, "onSingleTapConfirmed: " + e.getX() + " " + e.getY());
            return super.onSingleTapConfirmed(e);
        }
    });

実行、確認

それぞれのメソッドに Log.v(TAG, "(コメント)"); を追加してありますので、画面にいろいろなジェスチャーで操作して、ジェスチャーイベントが検出できていることを確認してください。

課題1

例題1のタッチイベントを使用して、画像(ImageView)をタッチして移動するプログラムを作成してください。

[ヒント]
ImageViewのスーパークラス(親クラス)であるViewは、レイアウトをプログラムで設定するメソッドが用意されています。

public void layout(int left, int top, int right, int bottom);

課題2

例題2のジェスチャーイベントを使用して、画像(ImageView)に対して以下のアクションを行うプログラムを作成してください。

  • 画面をスクロールすると、同じ方向に画像が平行移動する
  • 画面をダブルタップすると、画像サイズが少しずつ拡大する