2012-04-06 2 views
2

짧은 버전 : onTouchEvent에서 시간 기반 카운터를 시작하고 수동 LongTouch 감지와 같이 응답하기 전에 일정 시간이 경과했는지 확인하는 방법이 필요합니다.Android : 터치 이벤트에서 수동으로 롱 프레스를 구현하는 방법?

설명 : 두 손가락으로 튀어 오르는 화면에서/밖으로 슬라이드하는 사용자 지정 이미지보기가 있습니다. 드래그 이벤트를 추가하고 싶지만 길게 누르는 것보다 빠를 필요가 있습니다. onTouchEvent 당 한 번 업데이트되는 카운터를 사용하여 드래그 이벤트를 지연시킬 수 있으며, 예를 들어 10 카운트 만 드래그를 트리거하지만 카운터는 터치 이벤트 만 업데이트하고 손가락은 이동해야합니다.

초당 60 회 증가되는 활동 레벨 필드 인 시간 기반 카운터를 만들려면 어떻게해야합니까?

답변

0

답변 : 사용 시스템 클럭 (elapsedRealtime())와 언론이 시작된 이후 밀리 초를 측정합니다. 일단 당신이 그것의 걸림 새를 얻는 것을 시작하면.

1

안드로이드의 소스 코드를 살펴보십시오.

GestureDetector를 길게 누르면 "키 작동 중지"시 지연 메시지가 시작됩니다. 이 메시지가 "키 누르기"전에 나오면 길게 누르십시오.

소스 http://www.devdaily.com/java/jwarehouse/android/core/java/android/view/GestureDetector.java.shtml

+0

고맙지 만 제스처를 사용하지 않았습니다. 터치 이벤트를 수동으로 평가하는 것은 내가하고 싶은 일에 대해보다 융통성 있고 편리합니다. 터치 이벤트 시스템은 시간을 제외한 우수한 정보를 제공합니다. 따라서 터치 이벤트 내에서 프레스를 측정 할 수있는 간단한 시계가 필요합니다. ;) –

+0

물론, GestureDetector의 출처에 대해 살펴보면이 문제를 해결하는 방법을 보여줍니다. 지연된 메시지는 "시계"입니다. –

+0

소스를 보내 주셔서 감사합니다. 지금 찾고있어. –

1

내가 Action_Down가 발생했을 때 true로 일부 부울을 설정하는 것이 접근 할 방법에 그냥 링크. action_up이 발생하면 boolean을 false로 설정하십시오. 또한 action_down이 발생할 때 원하는 지연 시간으로 postDelayed를 설정하십시오. postdelayed에서 이전에 true로 설정 한 부울이 여전히 참이면 원하는 것을하십시오. 그런 말없는 대답에 대한 미안하지만, 어떻게 그것을 할 것입니다.

+0

좋아요, 당신이하는 말을 봅니다. 실행을 지연시키고 그것을 방해하십시오. 하지만 액션 뱅크 (ActionUp)를 실행하지 않기 때문에 그건 생각지 않습니다. 나는 두 가지 행동을 취했다. 1) 메뉴에서 아이콘을 드래그하십시오. 2) 두 손가락으로 메뉴를 켜거나 끄십시오. 드래그의 지연은 두 번째 손가락이 화면을 쳐야 만 가능합니다. 그렇지 않으면 드래그가 두 손가락 플링이 시작되기 전에 시작됩니다. 그래서 기본적으로 ACTION_DOWN 후 두 번째 포인터가 100ms가 아니라면 드래그하십시오. –

+0

아, 그래, 네 말이 무슨 말인지 알 겠어. 만약 내가 정확하게 기억한다면, 첫 번째 손가락은 0의 ID를 갖습니다. 위에서 언급 한 postDelayed를 할 것입니다. 그러나 두 번째 손가락을 인식하는지 또는 두 번째 손가락인지 인식하는지 여부는 결정적인 요소입니다. 두 번째 pointerIndex event.getAction = ActionDown 또는 ActionMove . 그런 것. 그냥 몇 가지 아이디어 – testingtester

+0

SystemClock을 사용하여 첫 번째 터치가 발생한 시간과 측정 된 시간을 측정 할 수 있습니다.: D –

7

질문이 확실하지 않지만 ACTION_UP 이벤트가 발생하기 전에 일종의 논리를 수행해야한다는 점을 제외하면 onTouchListener에서 catch long click 이벤트를 구현하려는 것 같습니다. 그렇다면 똑같은 문제가 있습니다. 또한 System.nanoTime() 사용하여 시도했지만 덜 까다로운 메서드를 발견했습니다. 타이머를 사용할 수 있습니다. 첫 번째 ACTION_DOWN 이벤트에서 일정을 예약하고 악영향이 발생하면 취소해야합니다 (예 : ACTION_UP은 길게 누르지 않고 클릭 만했거나 ACTION_MOVE는 특정 임계 값). 다음과 같은 뭔가 :

layout.seyOnTouchListener(new OnTouchListener(){ 
    private Timer longpressTimer; //won't depend on a motion event to fire 
    private final int longpressTimeDownBegin = 500; //0.5 s 
    private Point previousPoint; 

    switch(event.getAction()){ 

    case MotionEvent.ACTION_DOWN:{ 
     longPressTimer = new Timer(); 
     longpressTimer.schedule(new TimerTask(){ 
      //whatever happens on a longpress 
     }, longpressTimeDownBegin); 
     return true; //the parent was also handling long clicks 
    } 
    case MotionEvent.ACTION_MOVE:{ 
     Point currentPoint = new Point((int)event.getX(), (int)event.getY()); 

     if(previousPoint == null){ 
      previousPoint = currentPoint; 
     } 
     int dx = Math.abs(currentPoint.x - previousPoint.x); 
     int dy = Math.abs(currentPoint.y - previousPoint.y); 
     int s = (int) Math.sqrt(dx*dx + dy*dy); 
     boolean isActuallyMoving = s >= minDisToMove; //we're moving 

     if(isActuallyMoving){ //only restart timer over if we're actually moving (threshold needed because everyone's finger shakes a little) 
      cancelLongPress(); 
      return false; //didn't trigger long press (will be treated as scroll) 
     } 
     else{ //finger shaking a little, so continue to wait for possible long press 
      return true; //still waiting for potential long press 
     } 
    } 
    default:{ 
     cancelLongPress(); 
     return false; 
    } 
    } 
} 
+0

아마도 차이점은별로 없지만 최적화의 경우 숫자의 제곱근을 계산할 때 Math.sqrt() 함수를 제거하는 것이 좋습니다. 속도가 느려지는 경향이 있습니다. minDisToMove를 minSquareDisToMove로 변경하고 거리의 제곱을 임계 값으로 지정하십시오. 또한 longpressress를 감지하는 대안으로이 [answer] (http://stackoverflow.com/a/11679788/996298)를 참조하십시오. – manu3d

관련 문제