タッチイベントについて
端末の画面をタッチした情報はMotionEventとしてActivityやViewに通知されます。
MotionEventはさまざまな情報を持っています。
MotionEvent – Android Developers
- アクション(触れたのか、動かしたのか、離したのか)
- ポインタの数(何本の指で触っているのか)
- タッチした座標
これらは全てポインタごと別々に識別されていて、全てポインタのインデックスでアクセスすることが出来ます。(ポインタのIDではありません)
その辺りをごっちゃにしてハマった結果、Stackoverflowに投稿した質問がこちらです。Androidでマルチタッチ時のポインターIDを検出する方法(ちなみに投稿後に勘違いが原因であることに気づいた)
ポインタのインデックスは必ず0から始まり、getPointerCount() - 1まで割り振られます。
例えば2本の指でタッチしている場合、getPointerCount()は2を返します。1本目の指がポインタインデックス0で、2本目がインデックス1となります。
さらにこの状態で1本目の指を離すと、2本目の指のインデックスが0に変わります。
指を離す順番によってインデックスはころころ変わるため、特定のポインタを識別するのには使えません。
例えば人差し指、中指、薬指を使ったタップを考えましょう。途中で人差し指、薬指は離したり触れたりしているとします。しかし常に中指はつけたままにして、これをトラッキングしたいとします。この場合にはポインタインデックスを使うことは出来ません。
特定のポインタを識別するにはポインタIDを利用します。
一度タッチするとポインタにはIDが割り当てられ、そのIDは指を離すまで変わりません。
上記の例で言うと、中指を画面から離さないかぎり中指を示すポインタのIDは常に同じです。
一方で注意しなければいけないのは、座標を取得したりするメソッドの引数はポインタインデックスであるということです。
ポインタはIDで識別するけど、そのポインタの情報を取得するために必要なのはポインタインデックスです。
そのため、特定のポインタIDの座標を取得したりするには、findPointerIndex()メソッドを使って、IDからポインタインデックスを引き出す必要があります。
ポインタインデックスは常に0から始まり、他のポインタが増減する度に再割当てされます。一方でポインタを識別するIDは、指が触れたときに割り振られ画面に触れている限りその値は変わりません。
例えばこんな感じになります。
インデックス0 ID0 人差し指 インデックス1 ID1 中指 インデックス2 ID2 薬指 ↓この状態で人差し指を離す インデックス0 ID1 中指 インデックス1 ID2 薬指 ↓人差し指でタッチする インデックス0 ID0 人差し指 インデックス1 ID1 中指 インデックス2 ID2 薬指
ポインタIDとポインタインデックスの値は、指を押した順番と反対に離す分には一致したままですが、押した順番とは異なる離し方をすると値がズレます。
タッチイベントはリアルタイムに配信されるわけではありません。


