2010-05-22 17 views
10

Ho un pulsante con un OnClickListener. Per scopi illustrativi, si consideri un pulsante che mostra una finestra di dialogo modale:Gestione dei pulsanti rapidi sui pulsanti

public class SomeActivity ... { 

    protected void onCreate(Bundle state) { 
    super.onCreate(state); 

    findViewById(R.id.ok_button).setOnClickListener(
     new View.OnClickListener() { 
     public void onClick(View v) { 
      // This should block input 
      new AlertDialog.Builder(SomeActivity.this) 
      .setCancelable(true) 
      .show(); 
     } 
    }); 
} 

condizioni d'uso normali, viene visualizzata la finestra di allarme e blocca ulteriormente ingresso. Gli utenti devono chiudere la finestra di dialogo prima che possano toccare nuovamente il pulsante.

Ma a volte il pulsante OnClickListener viene chiamato due volte prima che venga visualizzata la finestra di dialogo. Puoi duplicarlo abbastanza facilmente toccando molto velocemente sul pulsante. Generalmente devo provare più volte prima che accada, ma prima o poi innescerò più chiamate onClick (...) prima che la finestra di dialogo blocchi l'input.

Vedo questo comportamento in Android 2.1 sul telefono Motorola Droid. Abbiamo ricevuto 4 rapporti sugli arresti anomali nel mercato, indicando che ciò accade occasionalmente alle persone.

A seconda di cosa fanno i nostri OnClickListener, questo provoca ogni sorta di scempio. Come possiamo garantire che i dialoghi di blocco bloccino effettivamente l'input dopo il primo tocco?

+0

Hai provato a creare AlertDialog all'esterno di onClick() e chiama semplicemente show() all'interno di onClick()? – jfpoilpret

risposta

17

Romain Guy ha confermato che si tratta di un bug in Android: "Succede solo se l'utente riesce a premere il pulsante due volte in < 125 ms. Credo che abbiamo risolto il possibile errore in Froyo."

Utilizzeremo il modello "riquadro di vetro" per aggirare l'errore nei sistemi operativi meno recenti. Cioè, copriremo lo schermo con una vista invisibile. Dopo il primo evento di clic, renderemo la vista "visibile" in modo da intercettare successivi eventi di tocco.

Non è sufficiente impedire ulteriori eventi con un solo pulsante. È necessario bloccare tutti gli eventi successivi per l'intera attività fino a quando la finestra di dialogo non viene chiusa, l'attività viene ripresa, ecc., A quel punto si rende di nuovo "invisibile" il riquadro di vetro.

Se ciò non funziona, dovremo solo conviverci e tollerare meglio eventi extra inaspettati.

+0

Wow ... sei * il * Bob Lee? –

+0

Immagino che dipenda da chi "è" Bob Lee. :-) Non conosco altri programmatori di Bob Lee. :-) –

+1

Bob e io stiamo andando con qualcosa di molto simile a ciò che Bob descrive sopra. La differenza principale è che il nostro "pannello di vetro" non è una vista reale. Invece, tutte le nostre attività estendono un'attività di base comune e tutte le nostre finestre di dialogo estendono una finestra di dialogo di base. Dal momento che abbiamo queste classi base, siamo in grado di introdurre una bandiera booleana in ciascuna. Questo flag indica se accettiamo o blocciamo input. In ciascuna di queste classi di base, si esegue l'override di dispatchTouchEvent. Sulla base della bandiera, possiamo semplicemente restituire true, che intercetta e blocca l'evento. Questo approccio sembra funzionare. –

9

Grazie per aver provato, mdma, ma questo è un problema di piattaforma, non un problema con il nostro codice. Peggio ancora, apparentemente non è un problema che può essere aggirato nel codice utente (richiede dettagli dal driver del touchscreen che non vengono trasmessi). Inoltre, il tuo esempio di codice non fa quello che pensi che faccia. show() non mostra immediatamente la finestra di dialogo. Aggiunge un messaggio alla fine della coda degli eventi che alla fine mostra la finestra di dialogo. Altri eventi di tocco potrebbero essere già in coda in attesa di essere eseguiti dopo i ritorni di onClick().

Non sono sicuro del motivo per cui le persone votano questa risposta.

+0

Ciao, ho cancellato la mia risposta. Ma non vedo come non sia possibile determinare se ci si trova tra gli stati - tra la gestione del clic e la visualizzazione della finestra di dialogo, e quindi ignorare ulteriori clic. – mdma

Problemi correlati