본문 바로가기

Android/2D 그래픽스

[Android] Touch Event

지난 포스트 [Android] Invalidate 화면을 갱신한다.에서 잠깐 나오기도 했지만 이번에는 간단한 터치 이벤트에 관한 포스트를 작성하고자 한다.

onTouchEvent(MotionEvent event)

Implement this method to handle touch screen motion events.


View를 손가락으로 터치했음을 감지하는 메소드는 View클래스가 가지고 있는 onTouchEvent라는 메소드이다. 인자로 받아오는 MotionEvent안에는 많은 정보가 들어 있는데 대표적으로는 현태 터치가 어떤 형태의 이벤트인가, 터치가 실행 된 좌표의 값은 무엇인가가 있다.

ACTION_DOWM
    화면을 터치하는 순간 발생

ACTION_UP
    화면에서 손을 떼는 순간 발생
ACTION_MOVE 
    화면을 터치한 채 움직일 때 발생 


액션의 종류에도 여러가지가 있지만 가장 대표적으로 사용되는 액션은 위의 세가지 액션이다.

여기서 주의할 점이 있다. onTouchEvent메소드는 boolean형태의 리턴을 받는다. 보통 super.onTouchEvent(event); 로 리턴을 하게되면 false값이 리턴이 되는데, false를 리턴해 버리면 연속되는 ACTION_MOVE, ACTION_UP의 이벤트는 받아올 수 없다.

다음의 예제는 드래그 하는 대로 따라오는 아이콘을 구현한 코드이다.


package com.cashyalla.graphics;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.View;

public class TouchEvent extends View {
	/** 아이콘 비트맵 */
	private Bitmap mBitmap;
	/** 비트맵의 최초 x좌표 */
	private float x = 0.0f;
	/** 비트맵의 최초 y좌표 */
	private float y = 0.0f;
	/** 지난 터치의 x좌표 */
	private float prevX = -1;
	/** 지난 터치의 y좌표 */
	private float prevY = -1;
	
	public TouchEvent(Context context) {
		super(context);
		// 리소스로부터 아이콘 이미지를 불러온다.
		mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// 현재의 x, y좌표를 기준으로 이미지를 그려준다.
		canvas.drawBitmap(mBitmap, x, y, null);
	}
	
	public boolean onTouchEvent(MotionEvent event) {
		// 현재의 터치 액션의 종류를 받아온다.
		int action = event.getAction();
		// 터치 된 x좌표
		float x = event.getX();
		// 터치 된 y좌표
		float y = event.getY();
		// 액션의 종류에 따른 역할 수행
		switch (action) {
		// 드래그 되었을 때의 이벤트 처리
		case MotionEvent.ACTION_MOVE :
			// 터치 좌표가 이미지 안에 들어와 있다면 드래그 된 만큼 이미지의 좌표도 이동시킨다.
			if (x > this.x && x < this.x + mBitmap.getWidth()
					&& y > this.y && y < this.y + mBitmap.getHeight()) {
				if (prevX > 0 && prevY > 0) {
					this.x += x - prevX;
					this.y += y - prevY;
				}
				// 현재의 좌표들이 지난 좌표가 된다.
				prevX = x;
				prevY = y;
				// 좌표 이동이 끝났으면 화면을 갱신한다.
				invalidate();
			}
			break;
		}
		return true;
	};
}