Please Enable JavaScript!
Gon[ Enable JavaScript ]

화면의 Touch Event 정보와 Message 구현

안드로이드 개발
반응형

화면의 Touch Event 정보와 Message 구현 


이번 예제는 안드로이드 화면상에 Touch 이벤트가 발생했을 때 어떻게 정보를 캡쳐해서

사용하는지와 이벤트 발생시 안드로이드 Message 객체를 사용해서 화면을 재로딩하는

방법에 대해 알아본다.


소스는 다음과 같이 이루어져 있다.

MainTouch : 메인 Activity

MessageList : 공통 메시지

TouchView : 화면 View

TickHandler : 메시지 캡쳐를 위한 Handler

 

1. MainTouch

(1) onCreate

View 를 상속받은 TouchView 등록한다.

 

(2) Handler 해제와 생성

onResume() 함수를 override 해서 TickHandler 객체를 생성한다. onResume Activity

생성될 때 와 다른 Activity 로 전환되어 Pause 되었다가 다시 시작될 때 실행되는 부분이다.

onPause() 함수가 실행될 때 TickHandler 객체를 삭제한다. 이것은 위에서 설명했듯이 Activity

전환해서 Fouse를 잃었을 때 발생하는 함수이다.

 

(3) 화면무효화를 통한 View 화면 새로 그림

onTick() 함수에서 View 객체의 invalidate() 함수를 호출해 화면을 새로 그린다. 화면에 대한

정보는 이미 View 객체의 onDraw() 함수에서 실행된 상태이다. 이 함수의 실행은 TickHandler

수행된다. 실행하고 o.1 sleep 을 걸어준다.
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Window;

public class MainTouch extends Activity{
	private TouchView touchView; // 터치뷰
	private TickHandler tickHandler;// 정기처리핸들러

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		touchView = new TouchView(this);
		setContentView(touchView);
	}
	/**
	 * Handler 를 리턴한다
	 * @return
	 */
	public TickHandler getHandler(){
		return tickHandler;
	}
	/* Activity 가 재시작 되었을때 Handler 재등록
	 * @see android.app.Activity#onResume()
	 */
	@Override
	public void onResume() {
		super.onResume();
		tickHandler = new TickHandler();
		tickHandler.sleep(0);
	}
	/* Activity 가 멈추었을때  Handler 객체 삭제
	 * @see android.app.Activity#onPause()
	 */
	@Override
	public void onPause() {
		super.onPause();
		tickHandler = null;
	}

	/**
	 * 화면 무효화를 통해 새로 그린다. 그리고 핸들을 0.1 초 멈춘다.
	 */
	public void onTick() {
		Log.d("MainTouch", "==============Refersh=============");
		touchView.invalidate();
		if (tickHandler != null)
			tickHandler.sleep(100);
	}

	// 주기처리핸들러
	public class TickHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			Log.d("TickHandler", "Handler Message : " + msg.toString());
			switch (msg.what){
			case MessageList.MSG_REFRESH:
				onTick();
				break;
			default:
				super.handleMessage(msg);
				break;
			}
		}

		// 슬립
		public void sleep(long delayMills) {
			removeMessages(0);// 해당 ID 메시지를 삭제한다.
			sendMessageDelayed(obtainMessage(0), delayMills); // 파라미터로 넘긴 ID 에 해당하는 msg 재사용
		}
	}
}

2. MessageList.java

메시지에 대한 상수값을 변수로 정의하기 위해 따로 static 클래스를 하나 만들었다.

이것은 모든 클래스에서 공통으로 쓰기 위함이다.
public class MessageList {
	public static final int MSG_REFRESH = 1;
}

3. TickHandler.java

MainTouch 클래스에 포함되어있다 .

(1) Handler 클래스 상속

사용자 정의 메시지를 중간에 가로채서 기능을 수행한다.

 

(2) 함수 종류

- handleMessage() : 핸들러메세지큐에 있는 작업을 처리 ( 실제 처리 메소드)

- obtainMessage() : Message가 필요할때 Handler.obtainMessage() Message.obtain()

    사용해서 풀에 있는 안쓰는 Message를 가져와서 재사용

- post() : 핸들러 메세지 큐에 Runnable 형태로 보낸다.

- removeMessages() : 핸들러 메세지 큐에서 메시지를 제거한다.

- sendMessage() : 핸들러 메세지 큐에 메세지 형태로 보낸다.

- sendMessageDelayed() : 핸들러 메세지 큐에 delay후에 메세지를 보낸다

 

(3) 원하는 메시지 걸러내기

handleMessage() 함수의 파라미터로 넘어오는 Message 에서 what 변수값은 message id 가 된다

id 로 구분해서 원하는 기능을 수행하면된다.
// 주기처리핸들러
	public class TickHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			Log.d("TickHandler", "Handler Message : " + msg.toString());
			switch (msg.what){
			case MessageList.MSG_REFRESH:
				onTick();
				break;
			default:
				super.handleMessage(msg);
				break;
			}
		}

		// 슬립
		public void sleep(long delayMills) {
			removeMessages(0);// 해당 ID 메시지를 삭제한다.
			sendMessageDelayed(obtainMessage(0), delayMills); // 파라미터로 넘긴 ID 에 해당하는 msg 재사용
		}
	}

4. TouchView.java

(1) onTouchEvent Override

화면 터치이벤트가 일어났을 때 정보를 가져오기 위해 onTouchEvent 함수를 Override 한다.

여기에서 넘어온 파라미터로 화면좌표를 전역변수에 저장해주고 사용자 정의 메시지를 날려준다
android.os.Message msg = new android.os.Message();
msg.what = MessageList.MSG_REFRESH;
msg.obj = "REFRESH";
handler.sendMessage(msg);

(2) 화면 그리기

onDraw() 함수를 override 한 함수에서 화면을 그리기 위한 정보들을 셋팅한다.

전역번수에 저장해 두었던 좌표와 MotionEvent 정보로 Down, Up, Move, Cancel 정보를 구분해

화면를 그려주고 있다.
canvas.drawText(
     "[Touch DOWN] X=" + downX + ",Y=" + downY, 0, 20 * 1, paint);
canvas.drawText(
     "[Touch MOVE] X=" + moveX + ",Y=" + moveY, 0, 20 * 2, paint);
canvas.drawText(
     "[Touch UP] X=" + upX + ",Y=" + upY, 0, 20 * 3, paint);
canvas.drawText(
     "[Touch CANCEL] X=" + cancelX + ",Y=" + cancelY, 0, 20 * 4, paint);
전체소스는 다음과 같다
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;

import com.gon.touchevent.MainTouch.TickHandler;

public class TouchView extends View {
	private int touchX = 0; // 터치X좌표
	private int touchY = 0; // 터치Y좌표
	private int touchAction = -999;// 터치액션
	private int ballX = 0; // 볼X좌표
	private int ballY = 0; // 볼Y좌표
	private int ballAction = -999; // 볼액션
	
	private Context mContext = null;
	
	// 터치액션 그리기
	int downX = 0, downY = 0;
	int moveX = 0, moveY = 0;
	int upX = 0, upY = 0;
	int cancelX = 0, cancelY = 0;
	
	// 생성자
	public TouchView(Context context) {
		super(context);
		setBackgroundColor(Color.WHITE);
		// 포커스지정
		setFocusable(true);
		
		mContext = context;
	}

	// 그리기
	@Override
	protected void onDraw(Canvas canvas) {
		String str;

		// 페인트 객체생성
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextSize(16);
		
		str = "NONE";
		if (touchAction == MotionEvent.ACTION_DOWN){
			downX = touchX;
			downY = touchY;
		}
		if (touchAction == MotionEvent.ACTION_MOVE){
			moveX = touchX;
			moveY = touchY;
		}
		if (touchAction == MotionEvent.ACTION_UP){
			upX = touchX;
			upY = touchY;
		}
		if (touchAction == MotionEvent.ACTION_CANCEL){
			cancelX = touchX;
			cancelY = touchY;
		}
		// DOWN XY좌표 그리기
		canvas.drawText("[Touch DOWN] X=" + downX + ",Y=" + downY, 0, 20 * 1, paint);
		canvas.drawText("[Touch MOVE] X=" + moveX + ",Y=" + moveY, 0, 20 * 2, paint);
		canvas.drawText("[Touch UP] X=" + upX + ",Y=" + upY, 0, 20 * 3, paint);
		canvas.drawText("[Touch CANCEL] X=" + cancelX + ",Y=" + cancelY, 0, 20 * 4, paint);

		// 볼XY좌표 그리기
		canvas.drawText("[TrackballXY] X=" + ballX + ",Y=" + ballY, 0, 20 * 6, paint);

		// 볼 액션 그리기
		str = "NONE";
		if (ballAction == MotionEvent.ACTION_DOWN)
			str = "ACTION_DOWN";
		if (ballAction == MotionEvent.ACTION_MOVE)
			str = "ACTION_MOVE";
		if (ballAction == MotionEvent.ACTION_UP)
			str = "ACTION_UP";
		if (ballAction == MotionEvent.ACTION_CANCEL)
			str = "ACTION_CANCEL";
		canvas.drawText("[TrackballAction]" + str, 0, 20 * 7, paint);
	}

	// 터치이벤트 처리
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		touchX = (int) event.getX();
		touchY = (int) event.getY();
		touchAction = event.getAction();
		
		// 다시 그리기 위해 핸들러에 메시지를 전송한다
		MainTouch mainTouch = (MainTouch) mContext;
		TickHandler handler = mainTouch.getHandler();
		
		android.os.Message msg = new android.os.Message();
		msg.what = MessageList.MSG_REFRESH;
		msg.obj = "REFRESH";
		handler.sendMessage(msg);
		
		return true;
	}

	// 트랙볼 이벤트 처리
	@Override
	public boolean onTrackballEvent(MotionEvent event) {
		ballX = (int) (event.getX() * 100);
		ballY = (int) (event.getY() * 100);
		ballAction = event.getAction();
		return true;
	}
}

화면상에서 어떻게 나타나는지 그림을 통해 보자.

마우스를 클릭했을떄 Down 위치정보가 바뀌며 클릭한 상태에서 움직이게 되면 Move

위치정보가 바뀌는걸 볼수 있다.

반응형
Posted by 녹두장군

댓글을 달아 주세요

  1. Favicon of http://k77.go5.kr 하면 되더라 2010.11.03 16:52  댓글주소  수정/삭제  댓글쓰기

    꿈희망ⓜ 좋은 글 잘 보고갑니다. 좋은 꿈 꾸세요. 드디어 님의 꿈은 이루어 집니다.