안드로이드 개발 사이트를 통해 MotionEvent를 이용 시 현재 터치 접점이 몇 개인지 확인할 수 있는 API를 확인하였다.

 final int TOUCH_POINT   = 2;

 //for navigation
 int[] _ox = new int[TOUCH_POINT]; //origin x
 int[] _oy = new int[TOUCH_POINT]; //origin y
 int[] _cx = new int[TOUCH_POINT]; //current x
 int[] _cy = new int[TOUCH_POINT]; //current y

 @Override 
 public boolean onTouchEvent(MotionEvent event) {     
  int _keyAction = event.getAction(); 
   //get the number of pointer, 2접점 이상은 현재 프로세스에서 필요가 없기 때문에 항상 두 접점까지만 산출
  int _count = event.getPointerCount()>TOUCH_POINT?TOUCH_POINT:event.getPointerCount();
   
  for (int i = 0; i < _count; i++) {
   _cx[i] = (int)event.getX(i); // View에 대한 상대 좌표
   _cy[i] = (int)event.getY(i); // View에 대한 상대 좌표
  }

  switch (_keyAction){ 
  case  MotionEvent.ACTION_POINTER_2_DOWN:   
   for (int i = 0; i < _count; i++) {
    _ox[i] = _cx[i];
    _oy[i] = _cy[i];
   }
   break;
    
  case MotionEvent.ACTION_MOVE:
   break;
  }
}

두 접점이 눌러졌을때 key action은 위 소스코드와 같이 ACTION_POINTER_2_DOWN 이라는 이벤트가 발생한다. 이때 기존 접점에 대한 정보를 저장한 후 실제 터치된 포인트가 이동 될 시 줌인/줌 아웃 이벤트를 발생시킬 예정이다.

아래의 소스코드는 ACTION_MOVE 내부에 들어가게 된다.

if(_number > 1) {
    //멀티 터치
     int _ow = Math.abs(_ox[0] - _ox[1]);
     int _oh = Math.abs(_oy[0] - _oy[1]); 
     int _cw = Math.abs(_cx[0] - _cx[1]);
     int _ch = Math.abs(_cy[0] - _cy[1]);
     
     int _ol = (int)Math.hypot(_ow, _oh);
     int _cl = (int)Math.hypot(_cw, _ch);
     
     if((_ol - _cl) > MULTI_SENSITIVITY) {
      //연속적인 이벤트 방지를 위한 로직
      for (int i = 0; i < _count; i++) {
       _ox[i] = _cx[i];
       _oy[i] = _cy[i];
      }
      zoomOut();
     } else if((_ol - _cl) <  -MULTI_SENSITIVITY) {
      //연속적인 이벤트 방지를 위한 로직
      for (int i = 0; i < _count; i++) {
       _ox[i] = _cx[i];
       _oy[i] = _cy[i];
      }
      zoomIn();
     }
} else {
//싱글터치 프로세스
}

현재의 접점 포인터의 갯수를 가지고 왔으니 이를 이용해 두 접점까지의 거리를 산출하여 거리가 줄어들었을때 / 거리가 늘어났을때를 분기하여 현재 애플리케이션에 적합한 민감도보다 큰 이벤트가 들어왔을때 줌인/줌아웃을 구현하는 것이 기본 컨셉이 되었다.

차트를 그릴때 싱글/멀티 터치에 따라 각각의 프로세스가 달라지기 때문에 이 또한 접점의 갯수에 따라 분기하였다.

또한 접점의 이동시 줌인/아웃이 연속적으로 발생하는 부분을 방지하기 위해 각 이벤트 설정 후 origin 좌표를 초기화 하는 로직이 추가되었다.

이로서 클라이언트가 요구하는 멀터터치를 이용한 줌인 줌 아웃 구현이 완성되었다.

애플리케이션의 특색에 따라 보다 부드러운 줌인/줌아웃의 구현이 필요할때에는 연속적인 이벤트 방지 로직을 삭제 후 이용해도 무방 할 것으로 보인다.

참조자료 (http://developer.android.com/reference/android/view/MotionEvent.html#getPointerCount())

원본자료 : http://ilovekenzo.tistory.com/category/Android/tip
블로그 이미지

s나그네s

안드로이드 개발

,