화면의 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
위치정보가 바뀌는걸 볼수 있다.'안드로이드 개발' 카테고리의 다른 글
안드로이드 어플 화면 캡쳐하기 (0) | 2010.10.15 |
---|---|
안드로이드 단말기와 이클립스 연결 (6) | 2010.09.13 |
모바일 웹의 폭발적 증가 에 대한 생각 (0) | 2010.09.07 |
Android - 프로그램에서 전화걸기 (7) | 2010.08.31 |
안드로이드 개발을 위한 환경설정과 프로젝트 생성 (10) | 2010.08.31 |
안드로이드(Android)에서 설치한 프로그램 삭제하기 (0) | 2010.08.31 |
안드로이드(Android) 기본 프로젝트 생성 (0) | 2010.08.31 |
안드로이드(Android) SD 카드에 이미지나 파일 추가하기 (7) | 2010.08.25 |