관리 메뉴

moozi

그래픽 2D 4 - onTouchEvent 사용하기 본문

안드로이드개발강좌

그래픽 2D 4 - onTouchEvent 사용하기

moozi 2010. 3. 9. 20:13

이번 강좌는 [ 안드로이드 개발 2.0 ] 그래픽 2D 3 - SurfaceView 활용 2 ] 에서 이어집니다.

지난 강좌에서 화면에 안드로이드 마스코트 아이콘을 띄웠습니다. 이번 강좌에서는 이 아이콘이 화면을 터치한 위치로 이동하도록 코드를 작성해 보겠습니다.


1. CustomView 클래스의 생성자를 다음과 같이 작성합니다.

public CustomView(Context context) {
            super(context);
            getHolder().addCallback(this);
            CVThread = new CustomViewThread(getHolder(), this);
            setFocusable(true);
        }

기존 코드에 setFocusable(true); 가 추가되었습니다. setFocusable(true);  는 해당 View가 touch mode에서 Focus가 가도록 지정합니다.


2. CustomView 클래스에서 터치한 위치를 표시하는 x, y 멤버변수를 사용하도록 다음과 같이 작성합니다.

class CustomView extends SurfaceView implements SurfaceHolder.Callback {
        private CustomViewThread CVThread;
        private int x = 70;
       private int y = 70;

 
        ...... 중간 생략

        @Override
        public void onDraw(Canvas canvas) {
         Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
            canvas.drawColor(Color.parseColor("#dedede"));
            canvas.drawBitmap(bm, x, y, null);
        }
  
... 이하 생략
}

비트맵이 표시되는 좌표를 x, y 변수에 저장해서 canvas.drawBitmap(bm, x, y, null); 에서 사용하고 있습니다.


3. 터치이벤트를 처리하는 onTouchEvent 메서드를 CustomView 클래스에 작성합니다.

@Override
        public boolean onTouchEvent(MotionEvent event) {
            x = (int) event.getX();
         y = (int) event.getY();
            return true;
        }

      x = (int) event.getX(); // x좌표
     y = (int) event.getY(); // y좌표


4. Ctrl + Shift + O 를 눌러서 pacakage들을 확실하게 추가한다음 Ctrl + F11 로 실행합니다.

[ 실행결과 ]

실행후 마우스를 이용해서 다른 위치를 클릭하면 해당위치로 아이콘이 이동하는 것을 알 수 있습니다.
그런데, 커서위치에 아이콘의 중심이 아닌 왼쪽 상단 부분이 위치합니다.(위의 그림을 잘 살펴보세요) 


5. 이미지의 중심이 터치한 위치에 오도록 onTouchEvent 메서드 내부를 다음과 같이 수정합니다.

@Override
        public void onDraw(Canvas canvas) {
         Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
            canvas.drawColor(Color.parseColor("#dedede"));
            canvas.drawBitmap(bm, x- (bm.getWidth() / 2), y - (bm.getHeight() / 2), null);
        }

터치한 위치를 이미지의 중심에 오게하려면, x좌표와 y좌표를 각각 가로, 세로 사이즈의 반만큼 왼쪽으로 이동하면 되므로 x- (bm.getWidth() / 2), y - (bm.getHeight() / 2) 와 같이 작성합니다.


6. 지금까지 작성한 CustomView 클래스의 전체 코드는 다음과 같습니다.

class CustomView extends SurfaceView implements SurfaceHolder.Callback {
        private CustomViewThread CVThread;
        private int x = 70;
        private int y = 70;
 
        public CustomView(Context context) {
            super(context);
            getHolder().addCallback(this);
            CVThread = new CustomViewThread(getHolder(), this);
            setFocusable(true);
        }
 
        @Override
        public void onDraw(Canvas canvas) {
         Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
            canvas.drawColor(Color.parseColor("#dedede"));
            canvas.drawBitmap(bm, x- (bm.getWidth() / 2), y - (bm.getHeight() / 2), null);
        }
       
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            x = (int) event.getX();
            y = (int) event.getY();
            return true;
        }
       
 
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            // TODO Auto-generated method stub
 
        }
 
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            CVThread.setRunning(true);
            CVThread.start();
        }
 
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
           
            boolean retry = true;
            CVThread.setRunning(false);
            while (retry) {
                try {
                    CVThread.join();
                    retry = false;
                } catch (InterruptedException e) {
                   
                }
            }
        }
    }

ctrl + F11 로 실행하면 다음과 같은 결과를 얻을 수 있습니다.

[ 실행결과 - 마우스 커서 위치에 아이콘의 중앙부분이 위치합니다. ]


Comments