X

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

mhidaka: Software Engineerだよ。DroidKaigi Organizer / Androidと組込とRe:VIEW。techbooster主宰。mhidaka's writings http://booklog.jp/users/mhidaka 技術書典! http://techbookfest.org