2011-11-22 18 views
7

Sto cercando di ignorare la funzionalità della pressione del tasto indietro. Quando l'utente lo preme una volta, voglio che ritorni alla schermata precedente. Tuttavia, quando si preme a lungo il tasto Indietro (per, diciamo, due secondi o più), voglio uscire dall'applicazione.Come distinguere tra la pressione lunga dei tasti e la pressione normale dei tasti?

Ormai, ho sovrascritto questi due metodi nella mia attività:

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event){ 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     //manage short keypress 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event){ 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     //manage long keypress (different code than short one) 
     return true; 
    } 
    return super.onKeyLongPress(keyCode, event); 
} 

Ma la onKeyLongPress callback viene mai chiamato, perché l'evento è sempre ricevuto dal metodo onKeyDown.

Esiste un modo per far funzionare entrambi i metodi? O deve essere fatto tutto nel onKeyDown e utilizzare il numero di ripetizioni/millisecondi per rilevarlo?

+0

fieno questo link [doc KeyEvent] (http://developer.android.com/reference/android/view/KeyEvent.Callback.html#onKeyDown%28int,%20android. view.KeyEvent% 29) –

risposta

12

Il motivo per cui onKeyLongPress non viene mai chiamato, è che si restituisce true in onKeyDown senza dire al framework che questa potrebbe essere una pressione prolungata, causando il blocco di KeyEvent attraverso i diversi gestori di eventi.

Quello che dovete fare è questo:

  1. Prima di restituire vero, chiamare event.startTracking() come spiegato nel documentation.
  2. Gestire la lunga pressione in onKeyLongPress.

Implementare come qui di seguito e funzionerà:

@Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if(keyCode == KeyEvent.KEYCODE_BACK) { 
     event.startTracking(); 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
    } 

    @Override 
    public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if(keyCode == KeyEvent.KEYCODE_BACK) { 
     //Handle what you want on short press.  
     return true; 
    } 

    return super.onKeyUp(keyCode, event); 
    } 

    @Override 
    public boolean onKeyLongPress(int keyCode, KeyEvent event) { 
    if(keyCode == KeyEvent.KEYCODE_BACK) { 
     //Handle what you want in long press. 
     return true; 
    } 
    return super.onKeyLongPress(keyCode, event); 
    } 
+0

Il problema è che prima di restituire true, devo fare alcune cose che sono completamente diverse se l'evento è per una normale stampa o una lunga pressione. Quindi, in ogni caso, devo rilevare la pressione prolungata sul metodo 'onKeyDown' prima di chiamare' startTracking', non è vero? –

+0

Ho modificato i commenti nel mio codice per mostrare cosa intendevo. Voglio solo restituire true in 'onKeyDown' se il keypress è breve. Altrimenti si propagano al gestore di pressione lunga del tasto. –

+0

Ho modificato la mia risposta per fornire la funzionalità richiesta. – kaspermoerch

2

perché non utilizzare onKeyUp() così come onKeyDown()? Durante lo onKeyDown() non si sa se si tratta di una pressione prolungata o meno, perché viene chiamata non appena si preme il tasto e non si sa per quanto tempo l'utente intende tenere premuto il tasto. Come dice correttamente KasperMoerch, devi chiamare startTracking nel tuo metodo onKeyDown() e restituire true. Quindi nel tuo onKeyUp() puoi chiamare event.isTracking() e event.isLongPress() per determinare se gestire le cose come una pressione prolungata o una pressione breve.

+0

Non funziona.'isTracking' restituisce true ma' isLongPress' restituisce false, nonostante io abbia premuto il pulsante per quasi 5 secondi. Forse questo non può essere testato sul simulatore? –

2

Penso che il modo migliore per gestirlo sia tale.

L'unico lato negativo che riesco a vedere qui è che il singolo clic sul pulsante del menu non emette alcun suono nel caso in cui l'utente lo abbia abilitato. Forse c'è un modo per controllare questa impostazione e usarla, o chiamare il comportamento predefinito.

Codice: controllare

private boolean _handledMenuButton=false; 

@Override 
public boolean onKeyUp(final int keyCode,final KeyEvent event) { 
    switch(keyCode) { 
     case KeyEvent.KEYCODE_MENU: 
      if (!_handledMenuButton) { 
       //Handle single clicking here 
      } 
      _handledMenuButton=false; 
      return true; 
    } 
    return super.onKeyUp(keyCode,event); 
} 

@Override 
public boolean onKeyLongPress(final int keyCode, final KeyEvent event) { 
    switch(keyCode) { 
     case KeyEvent.KEYCODE_MENU: 
      //Handle long clicking here 
      _handledMenuButton=true; 
      return true; 
    } 
    return super.onKeyLongPress(keyCode,event); 
} 

@Override 
public boolean onKeyDown(final int keyCode,final KeyEvent event) { 
    switch(keyCode) { 
     case KeyEvent.KEYCODE_MENU: 
      _handledMenuButton=false; 
      event.startTracking(); 
      return true; 
    } 
    return super.onKeyDown(keyCode,event); 
}