2011-09-01 5 views
1

메뉴 버튼을 누르면 한 번의 클릭 또는 두 번 클릭을 감지 할 수 있기를 원합니다. 한 번의 클릭이 감지 된 경우에도 두 번 클릭이 발생하면 다른 이벤트가 발생합니다. 여기에 내가 (이벤트 대신 토스트를 사용하여) 시도했습니다 것입니다 :메뉴 버튼을 누르면 어떻게 싱글 클릭 이벤트와 더블 클릭 이벤트를 만들 수 있습니까?

private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis 
private long lastPressTime; 

@Override 
public boolean onPrepareOptionsMenu(Menu menu) {  

    // Get current time in nano seconds. 
    long pressTime = System.currentTimeMillis(); 


    // If double click... 
    if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) { 
     Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show(); 
     return true; 
    } 

    // If not double click.... 
    Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show(); 

    // record the last time the menu button was pressed. 
    lastPressTime = pressTime;  
    return true; 
} 

문제는 단 한번의 클릭 이벤트가 더블 클릭 이벤트 전에 모든 시간을 감지한다는 것입니다.

+1

왜 긴 클릭을 사용하지 않습니까? – PedroAGSantos

+0

긴 클릭을 어떻게 감지합니까? 지금은 문서를 파고 있지만 작동하는 것을 찾지 못하고 있습니까? (지금은 길게 누르기 만하면 키보드가 나타납니다.) – jjNford

+0

나는 당신이 말하는 것을 보았습니다. 나는보기가 아닌 실제 키보드를 오래 클릭하고 싶다. 보기에는 이미 등록 된 긴 클릭이 있습니다. – jjNford

답변

14

간단한 논리 실수. 새로운 lastPressTime을 녹음하기 전에 돌아오고 있습니다. 내가 홀드 이벤트 (긴 클릭)뿐만 아니라 짧은 더블 클릭을 감지하는이 코드를 수정

boolean mHasDoubleClicked = false; 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) {  

     // Get current time in nano seconds. 
     long pressTime = System.currentTimeMillis(); 


     // If double click... 
     if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) { 
      Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show(); 
      mHasDoubleClicked = true; 
     } 
     else {  // If not double click.... 
      mHasDoubleClicked = false; 
      Handler myHandler = new Handler() { 
       public void handleMessage(Message m) { 
         if (!mHasDoubleClicked) { 
          Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show(); 
         } 
       } 
      }; 
      Message m = new Message(); 
      myHandler.sendMessageDelayed(m,DOUBLE_PRESS_INTERVAL); 
     } 
     // record the last time the menu button was pressed. 
     lastPressTime = pressTime;  
     return true; 
    } 
+1

더블 클릭으로 처음 버튼을 누르면 'else'케이스가 실행되고 싱글 클릭 이벤트가 토스트되고 'if'케이스가 바로 뒤 따르기 때문에 문제가 해결되지 않습니다. – jjNford

+0

아, 이제 알았습니다. 편집이 더 나은지 확인하십시오. 나는 그것이 컴파일되는지 확인하지 않았다. – Ian

+0

handleMessage 선언 다음에 세미콜론이 한 개 누락되었습니다. 하지만 완벽하게 작동합니다. 굉장해! 이 문제에 대한 답변을 찾기 위해 Google에서 검색 할 때 핸들러 객체를 사용한 적이 한번도 없었습니다. 엄청 고마워! – jjNford

0

: 당신은 그들이 모두 같은 일을 반환하는 경우 하나의 반환 호출이 있어야합니다. 이것은 이벤트가 아직 처리되지 않은 ACTION_UP 이벤트 (clickHandled == false)가 될 때까지 짧은 클릭의 감지를 지연시킴으로써 작동합니다.

onShortClick(), onLongClick() 및 onDoubleClick()에 대한 고유 한 메서드를 제공하십시오.

private long thisTouchTime; 
private long previousTouchTime = 0; 
private long buttonHeldTime; 
private boolean clickHandled = false; 
private long DOUBLE_CLICK_INTERVAL = ViewConfiguration.getDoubleTapTimeout(); 
private long LONG_HOLD_TIMEOUT = ViewConfiguration.getLongPressTimeout(); 

@Override 
public boolean onTouch(View v, final MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      thisTouchTime = System.currentTimeMillis(); 
      if (thisTouchTime - previousTouchTime <= DOUBLE_CLICK_INTERVAL) { 
       // double click detected 
       clickHandled = true; 
       onDoubleClick(event); 
      } else { 
       // defer event handling until later 
       clickHandled = false; 
      } 
      previousTouchTime = thisTouchTime; 
      break; 
     case MotionEvent.ACTION_UP: 
      if (!clickHandled) { 
       buttonHeldTime = System.currentTimeMillis() - thisTouchTime; 
       if (buttonHeldTime > LONG_HOLD_TIMEOUT) { 
        clickHandled = true; 
        onLongClick(event); 
       } else { 
        Handler myHandler = new Handler() { 
         public void handleMessage(Message m) { 
          if (!clickHandled) { 
           clickHandled = true; 
           onShortClick(event); 
          } 
         } 
        }; 
        Message m = new Message(); 
        myHandler.sendMessageDelayed(m, DOUBLE_CLICK_INTERVAL); 
       } 
      } 
      break; 
     case MotionEvent.ACTION_MOVE: 
      myParams.x = initialDrawX + (int) (event.getRawX() - initialTouchX); 
      myParams.y = initialDrawY + (int) (event.getRawY() - initialTouchY); 
      windowManager.updateViewLayout(v, myParams); 
      break; 
    } 
    return false; 
} 
관련 문제