タッチイベントを取得する(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()などがあります。