タッチイベントを取得する(onTouchEventとMotionEvent)
|Androidには様々な入力インターフェイスが備わっています。
ハードウェアキーボード、トラックボール、タッチスクリーンなどです。端末によっては複数の入力インターフェイスをサポートしていることがあります。今回は最も一般的なタッチスクリーンから、イベントを受け取る方法を解説します。
ユーザのスクリーン操作を受け取るにはonTouchEventメソッドを利用します。
ActivityとViewのTouchEvent
onTouchEventの呼び出し優先順位は上位のView>下位のView>Activityです。
クラスとメソッド | 説明 |
---|---|
Activity.onTouchEvent | Viewで消費されなかった場合、呼び出される |
View.onTouchEvent | 上位レイヤーから順番に呼び出される |
最も単純なソースコードは以下の通りです
public class touchEventActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d("TouchEvent", "X:" + event.getX() + ",Y:" + event.getY()); return true; } }
onTouchEventメソッドの返り値は標準でfalseですが、今回は、trueとしています。
返り値をtrueに設定すると「TouchEventを消化」したことになり、他のViewやActivityへの通知を抑制できます。
タッチパネルを指でなぞると以下のような座標値をLogcatへ出力します
07-26 16:59:22.098: DEBUG/TouchEvent(260): X:146.0,Y:320.0
07-26 16:59:22.120: DEBUG/TouchEvent(260): X:146.0,Y:316.0
07-26 16:59:22.139: DEBUG/TouchEvent(260): X:146.0,Y:316.0
07-26 16:59:24.898: DEBUG/TouchEvent(260): X:58.0,Y:154.0
MotionEventで受け取れるイベントは座標だけではなくAction(動作)など多様な情報を取り出せます。
Actionや境界値判定など続きで解説します
MotionEventの主なメソッドまとめ
特に使うシーンの多いMotionEventメソッド一覧です
MotionEventメソッド名 | 説明 |
---|---|
getX() , getY() | タッチされてたX,Y座標 |
getAction() | タッチイベントのアクション |
getDownTime() | 押されていた時間(ms単位) |
getEdgeFlags() | スクリーン端判定 |
getSize() | タッチされている範囲、サイズ(推定) |
getEventTime() | タッチされていた継続時間(ms単位) |
getPressure() | タッチされた圧力 |
Actionの取得と発生順序
最もよく使うのは、UP,DOWN,MOVE,CANCELに代表されれるActionです。
@Override public boolean onTouchEvent(MotionEvent event) { Log.d("TouchEvent", "X:" + event.getX() + ",Y:" + event.getY()); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("TouchEvent", "getAction()" + "ACTION_DOWN"); break; case MotionEvent.ACTION_UP: Log.d("TouchEvent", "getAction()" + "ACTION_UP"); break; case MotionEvent.ACTION_MOVE: Log.d("TouchEvent", "getAction()" + "ACTION_MOVE"); break; case MotionEvent.ACTION_CANCEL: Log.d("TouchEvent", "getAction()" + "ACTION_CANCEL"); break; } return true; }
MotionEvent.getAction()で取得できる動作
この中では ACTION_OUTSIDE が見慣れませんが、Viewの範囲外をタッチした場合に呼ばれます
定数名 | 説明 |
---|---|
ACTION_DOWN | 0x02 タッチ押下 |
ACTION_MOVE | 0x00 指を持ち上げずにスライドさせた場合 |
ACTION_UP | 0x01 指を持ち上げた場合 |
ACTION_CANCEL | 0x03 UP+DOWNの同時発生(=キャンセル)の場合 |
ACTION_OUTSIDE | 0x04 ターゲットとするUIの範囲外を押下 |
キャンセルの場合は、定数値0x03です。これはビットのOR演算で見ると、(0x02 | 0x01 )となり、DOWNとUPが同時に発生しています。
ユーザーは短期間のうちに指を離したことから、操作しようとしてやめています。DOWN/UPアクションは行わず、キャンセルで良いでしょう。
07-26 17:24:14.039: DEBUG/TouchEvent(288): X:164.0,Y:311.0
07-26 17:24:14.048: DEBUG/TouchEvent(288): getAction()ACTION_DOWN
07-26 17:24:14.079: DEBUG/TouchEvent(288): X:164.0,Y:317.0
07-26 17:24:14.079: DEBUG/TouchEvent(288): getAction()ACTION_MOVE
07-26 17:24:14.100: DEBUG/TouchEvent(288): X:165.0,Y:320.0
07-26 17:24:14.100: DEBUG/TouchEvent(288): getAction()ACTION_MOVE
07-26 17:24:14.129: DEBUG/TouchEvent(288): X:165.0,Y:321.0
07-26 17:24:14.129: DEBUG/TouchEvent(288): getAction()ACTION_MOVE
07-26 17:24:14.159: DEBUG/TouchEvent(288): X:165.0,Y:321.0
07-26 17:24:14.159: DEBUG/TouchEvent(288): getAction()ACTION_UP
アクションはDOWNから始まり、MOVE(複数回繰り返し)、UPの順番で発生します。
その他のメソッド
MotionEvent.getEdgeFlags()を使った画面端の判定
このメソッドの返り値はビット演算(OR)になっています。
定数名 | 説明 |
---|---|
EDGE_TOP | 0x01 上端に到達 |
EDGE_BOTTOM | 0x02 下端に到達 |
EDGE_LEFT | 0x04 左端に到達 |
EDGE_RIGHT | 0x08 右端に到達 |
その他にも、タッチスクリーンへの圧力を取得するMotionEvent.getPressure()や押された範囲を推定するMotionEvent.getSize()などがあります。