2016.09.23 01:26


ListView를 보시면 화면을 터치한 후 드래그하는 속도에 따라 ListView의 스크롤링 속도가 변하는 것을 볼 수 있습니다. 천천히 하면 스크롤도 천천히 되고 빠르게 드래그하면 바퀴 돌 듯이 ListView가 스크롤 되지요. 이런 효과는 어떻게 구현될 수 있을까요? 안드로이드에서 제공하는 클래스를 통해 쉽게 구현할 수 있습니다. 다음의 코드를 보시죠.


public class MyOnTouchListener implements OnTouchListener {

    private VelocityTracker mVelocityTracker;

    public boolean onTouch(View v, MotionEvent event) {

        if (mVelocityTracker == null) {

            mVelocityTracker = VelocityTracker.obtain();

        }

        mVelocityTracker.addMovement(event);


        switch (event.getAction()) { 

        case MotionEvent.ACTION_DOWN:

            Log.v(TAG"ACTION_DOWN");

            break



        case MotionEvent.ACTION_MOVE:

            Log.v(TAG"ACTION_MOVE");

            mVelocityTracker.computeCurrentVelocity(1);

            float velocity = mVelocityTracker.getXVelocity();

            break


        case MotionEvent.ACTION_UP:

            Log.v(TAG"ACTION_UP");

            if (mVelocityTracker != null) {

                mVelocityTracker.recycle();

                mVelocityTracker = null;

            }

            break

        } 

        return true;

    }

}


요점은 VelocityTracker가 드래그의 속도를 측정해준다는 것입니다. 위의 예제에서는 VelocityTracker의 5가지 메소드가 사용되었습니다.

1. obtain()
   이것은 정적 메소드입니다. VelocityTracker의 인스턴스를 구하기 위한 팩토리 메소드입니다.
2. addMovement(MotionEvent e)
   속도를 측정하기 위해서 VelocityTracker 인스턴스에 MotionEvent를 입력합니다.
3. computeCurrentVelocity(int unit)
   입력된 데이타를 기반으로 속도를 측정합니다. unit은 측정 시간 단위이며 1은 1밀리초를, 1000은 1초를 의미합니다. 다시 말해 unit이 1이라면 1밀리초동안의 픽셀단위의 이동 거리를 측정합니다.
4. getXVelocity()
   X축으로의 속도를 구합니다. Y축으로의 속도는 getYVelocity()를 사용하면 됩니다. 
5. recycle()
   객체를 재사용할 수 있도록 초기화 합니다.
   드래깅 속도 측정은 빈번하게 일어나는 연산입니다. 하지만 이를 위해서 각각의 OnTouchListener가 VelocityTracker의 인스턴스를 하나씩 점유하는 것은 분명 낭비입니다.(안드로이드는 임베디드 시스템을 위한 운영체제임!) 따라서 VelocityTracker 객체의 생성은 팩토리 메소드에 위임하고 객체는 사용 후 반환합니다. 그러면 결과적으로 VelocityTracker 객체 하나가 모든 드래깅 동작에 공유되어 사용될 수 있습니다. 




출처 : http://anddev.tistory.com/16


신고


Posted by injunech
2015.04.12 16:19


[Android] onTouchEvent 에서의 MotionEvent 터치 구분



@Override

public boolean onTouchEvent(MotionEvent event) {

int action = event.getAction();

int touch_id = ((action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> 8 );

int actionEvent = action & MotionEvent.ACTION_MASK; // MotionEvent.ACTION_MASK = 0xff

pointerCount = event.getPointerCount();


switch (actionEvent) {

case MotionEvent.ACTION_DOWN: {

...

}


위와 같이 action 값을 받게 되면 해당 action 값에는 Touch 동작 관련 HEX 값이 들어가게 된다

Integer.toHexString(action) 를 통해 int 값을 HEX 로 출력하면 16진수로 다음과같은 값으로 터치를 구분할 수 있다

0x___

세번째 두번째 첫번째


첫번째 값은 터치의 Up, Down, Move 를 판별 가능하며, 첫번째 터치인경우와 두번째 터치 이후의 터치의 경우 Up 과 Down 구분 값이 다음과 같이 달라진다.

     Primary Finger DOWN = 0        Primary Finger UP     = 1

non-Primary Finger DOWN 5   non-Primary Finger UP     = 6

All Finger MOVE             = 2


두번째 값은 0 이 입력되고 0 이외의 값은 본적이 없다. (나중에 추가로 조사를 해봐야 할듯)


세번째 값은 touch ID 값으로 첫번째 터치인경우 0의 값 두번째 터치인 경우 1의값 세번째 터치인 경우 2의 값이 들어가며 멀티 터치를 지원하는 최대 값까지 입력된다. 한개의 터치가 Release 되는 경우에는 아직 터치상태인 나머지 터치의 action 의 세번째 Hex 값은 첫번째 터치 값인 0부터 다시 차례대로 터치한 상태로 매겨지게 된다. 자세한 사항은 아래 참고의 예를 확인

- 참고 : 첫번째 터치시에 값은 0 두번째 터치시에 값은 1, 세번째 터치시에 값은 2 이다.

이상태에서 터치를 Release 하는 경우에는 해당 터치 ID 의 값이 입력된다.

예를 들면 3번째까지 터치한 상태에서 두번째 터치한 손가락을 Release 하는 경우에는 action의 세번째 Hex 값은 1이된다.

또한 이상태에서 현재 터치한 Count 값은 총 2개이다. 그리고 나머지 첫번째 터치한 action의 세번째 Hex 값은 그대로 0이고 세번째 터치한 action 의 세번째 Hex 값은 기존의 2에서 1로 변경되게 된다.





나같은 경우에는 위 코드와 같이 action 값을 세번째 Hex 값, 첫번째 두번째 Hex 값으로 아래와 같이 저장하여 이용한다.

int action = event.getAction();

int touch_id = ((action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> 8 );

int actionEvent = action & MotionEvent.ACTION_MASK; // MotionEvent.ACTION_MASK = 0xff






신고


Posted by injunech

티스토리 툴바