달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
728x90
반응형

안드로이드 - 멀티터치 구현하기 (드래그, 핀치투줌)

2011/03/18 14:55

복사 http://blog.naver.com/prosports0/80126529694

안드로이드 개발시

멀티터치를 구현하는 방법을 설명한다..


http://stackoverflow.com/questions/4227451/android-imageview-setting-drag-and-pinch-zoom-parameters

위의 자료를 참조하였다.


기본 원리는 터치 이벤트를 받아서 좌표를 구하는 방식이다.

크게 두가지의 터치 방식을 생각해볼수 있다.


1. 손가락 하나로 터치하여 드래그하는 방식.

- 처음 포인트의 위치와 드래그중의 위치의 거리를 비교하여 작업한다.

2. 두손가락을 동시에 드래그하는 핀치 투 줌(Pinch to zoom)방식이다.

- 터치 순서에 따라 인덱스 0 ,1을 부여하는데 이를 이용해서 (ex event.getX(0), event.getX(1))

두 포인트의 좌표를 가지고 두 포인트간의 거리를 측정한다.


주요 motion event로는

MotionEvent.ACTION_DOWN : 터치 시작(첫번째 터치)

MotionEvent.ACTION_POINTER_DOWN : 터치 시작(두번째 터치)

MotionEvent.ACTION_UP : 터치 종료(첫번째 터치)

MotionEvent.ACTION_POINTER_UP : 터치 종료(첫번째 터치)

MotionEvent.ACTION_MOVE : 드래그 중

MotionEvent.ACTION_MASK : 터치 이벤트 액션을 구분짓기 위한 MASK

으로 구분할 수 있다.


/***************************************************************************

소스 구현 부

***************************************************************************/

// 드래그 모드인지 핀치줌 모드인지 구분

static final int NONE = 0;

static final int DRAG = 1;

static final int ZOOM = 2;

int mode = NONE;

// 드래그시 좌표 저장

int posX1=0, posX2=0, posY1=0, posY2=0;

// 핀치시 두좌표간의 거리 저장

float oldDist = 1f;

float newDist = 1f;

public boolean onTouchEvent(MotionEvent event) {

int act = event.getAction();

String strMsg = "";

switch(act & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_DOWN: //첫번째 손가락 터치(드래그 용도)

posX1 = (int) event.getX();

posY1 = (int) event.getY();

Log.d("zoom", "mode=DRAG" );

mode = DRAG;

break;

case MotionEvent.ACTION_MOVE:

if(mode == DRAG) { // 드래그 중

posX2 = (int) event.getX();

posY2 = (int) event.getY();

if(Math.abs(posX2-posX1)>20 || Math.abs(posY2-posY1)>20) {

posX1 = posX2;

posY1 = posY2;

strMsg = "drag";

Toast toast = Toast.makeText(this, strMsg, Toast.LENGTH_SHORT);

toast.show();

}

} else if (mode == ZOOM) { // 핀치 중

newDist = spacing(event);

Log.d("zoom", "newDist=" + newDist);

Log.d("zoom", "oldDist=" + oldDist);

if (newDist - oldDist > 20) { // zoom in

oldDist = newDist;

strMsg = "zoom in";

Toast toast = Toast.makeText(this, strMsg, Toast.LENGTH_SHORT);

toast.show();

} else if(oldDist - newDist > 20) { // zoom out

oldDist = newDist;

strMsg = "zoom out";

Toast toast = Toast.makeText(this, strMsg, Toast.LENGTH_SHORT);

toast.show();

}

}

break;

case MotionEvent.ACTION_UP: // 첫번째 손가락을 떼었을 경우

case MotionEvent.ACTION_POINTER_UP: // 두번째 손가락을 떼었을 경우

mode = NONE;

break;

case MotionEvent.ACTION_POINTER_DOWN:

//두번째 손가락 터치(손가락 2개를 인식하였기 때문에 핀치 줌으로 판별)

mode = ZOOM;

newDist = spacing(event);

oldDist = spacing(event);


Log.d("zoom", "newDist=" + newDist);

Log.d("zoom", "oldDist=" + oldDist);

Log.d("zoom", "mode=ZOOM");

break;

case MotionEvent.ACTION_CANCEL:

default :

break;

}

return super.onTouchEvent(event);

}

private float spacing(MotionEvent event) {

float x = event.getX(0) - event.getX(1);

float y = event.getY(0) - event.getY(1);

return FloatMath.sqrt(x * x + y * y);

}

728x90
반응형
:
Posted by mapagilove