LoginSignup
4
1

More than 5 years have passed since last update.

View#onTouchEvent を実装したが最初のタッチのイベントしか来ない

Posted at

解を先に書くと「onTouchEvent の戻り値を true にせよ」

検索してもなかなか見つからず解決に行き着くのに苦労してしまったのでメモ。

経過

  • 動機:マルチタッチのイベントの様子を観察してみよう。
  • 実装:
    • 既存アプリに導入しやすくするには透明な View として実装すればいいかな。
    • View レベルで実現するには android.view.View を継承して onTouchEvent を実装すればよいと。
    • Android Studio で onTouchEvent 補完、どん。(この時点で自動生成されたコードは return super.onTouchEvent(event); になっている。これが間違い。)
    • 引数の MotionEvent を適当にログに吐き出してみると。
  • 実行してみる:
    • あれ?最初のタッチの ACTION_DOWN しか制御がこない。なんで?
    • UP さえもこない。
    • 全部離して再度タッチすると、その最初は来るな。
  • 調べる:
    • 公式チュートリアルみても onTouchEvent を実装って書いてある。
    • マルチタッチを受け取るために何か set 系や request 系などの設定は必要ないみたいだし。
    • Activity に onTouchEvent を実装するとちゃんと来てる。ということは環境の問題ではない。
    • マルチタッチの実装記事を見ても何も無いし。なんで~? →探し回る。
    • http://stackoverflow.com/a/12588509/3180048 これかー

対策

View の onTouchEvent が false を返すと、そのジェスチャーに関する以降のイベントはその View に送られなくなる。 なので true を返せ、と。

後知恵

onTouchEvent のドキュメントの戻り値の説明は

True if the event was handled, false otherwise.

となっている。以降のイベントがどうのなんて書いてない...。

そして自動生成された return super.onTouchEvent(event); は false を返すと。

追加考察

となると、今回狙おうとしたイベント的に透明な View というのは書けないようだ。
Android のタッチイベントを理解する(その1) によれば、
ViewGroup にして onInterceptTouchEvent を使うと子への配信前に呼ばれるらしい。ただし requestDisallowInterceptTouchEvent があるので子からの干渉が可能と。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1