2010-11-03 5 views
24

Su un solo telefono su cui sto eseguendo il test (HTC Incredible, Android 2.2, Software 3.21.605.1), sto riscontrando il seguente comportamento.OnEditorActionListener chiamato due volte con lo stesso eventoTime sulla tastiera SenseUI

Il gestore di eventi onEditorAction viene chiamato due volte (immediatamente) quando si preme il tasto Invio sulla tastiera UI Senso.

Il KeyEvent.getEventTime() è lo stesso per entrambe le volte l'evento è chiamato, mi porta a questo work-around:

protected void onCreate(Bundle savedInstanceState) { 
    [...] 

    EditText text = (EditText)findViewById(R.id.txtBox); 
    text.setOnEditorActionListener(new OnEditorActionListener() { 
     private long lastCalled = -1; 

     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
      if (event.getEventTime() == lastCalled) { 
       return false; 
      } else { 
       lastCalled = event.getEventTime(); 
       handleNextButton(v); 
       return true; 
      } 
     } 
    }); 

    [...] 
} 

L'EditText è definito come:

<EditText 
    android:layout_width="150sp" 
    android:layout_height="wrap_content" 
    android:id="@+id/txtBox" 
    android:imeOptions="actionNext" 
    android:capitalize="characters" 
    android:singleLine="true" 
    android:inputType="textVisiblePassword|textCapCharacters|textNoSuggestions" 
    android:autoText="false" 
    android:editable="true" 
    android:maxLength="6" 
/> 

On tutti gli altri dispositivi su cui ho provato, il pulsante di azione è etichettato correttamente "Avanti" e l'evento viene chiamato una sola volta quando viene premuto quel pulsante.

Si tratta di un errore nella tastiera di Sense UI o sto facendo qualcosa in modo errato?

Grazie per l'assistenza.


Aggiornato - grazie alle risposte fornite, ho stabilito quanto segue come miei assegni. Questo funziona bene su entrambi i telefoni che ho a disposizione per prova (Sense UI e CyanogenMod CM7)

  if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) { 
       return false; 
      } 

      if (actionId != EditorInfo.IME_ACTION_NEXT && actionId != EditorInfo.IME_NULL) { 
       return false; 
      } 
+2

Nessuna risposta per te, ho paura, volevo solo dire che oggi sono stato colpito da questo problema. Non avevo mai visto la tastiera HTC Sense prima di oggi .. ugh!E come sono riusciti a ignorare il flag textNoSuggestions? Rende la mia interfaccia utente un po 'schifosa, marcandoli. –

+0

Ho notato che molte app non funzionano correttamente dato che la loro tastiera non implementa il pulsante predefinito (è sempre "Invio"). Ciò include le applicazioni fornite da Google (inclusa, credo, la procedura di registrazione iniziale). Sembra una cosa abbastanza grande da trascurare per HTC. È un peccato, perché in realtà mi piace SenseUI su tutti più di Motoblur. Grazie per la conferma. – mbafford

risposta

26

Come ha detto Mitch, si controlla l'azione evento:

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
    if (event.getAction() != KeyEvent.ACTION_DOWN) 
     return false; 

    // do your stuff 

    return true; 
} 

Questo frammento funziona sia sul Sense UI e l'emulatore.

+2

Sembra quasi la risposta, anche se sul mio altro telefono (con CyanogenMod CM7), "evento" è nullo quando premo "Avanti" sulla tastiera, quindi devo controllare anche quello. – mbafford

+1

Ho anche aggiunto un "if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED) return false;" al metodo. – AlexVogel

0

invece di inviare un'azione ime e nulla come un evento, invia un evento di tocco quindi se il vostro non ottenere la azione corretta è possibile controllare l'evento per action_up o action_down

+1

Non capisco cosa stai dicendo qui. C'è un evento che funzionerà correttamente su HTC Sense UI e altre tastiere che implementano correttamente l'azione predefinita? – mbafford

3
(EditText) passwordView = (EditText) findViewById(R.id.password); 
passwordView.setImeOptions(EditorInfo.IME_ACTION_DONE); 
    passwordView.setOnEditorActionListener(new OnEditorActionListener() 
     { 
      @Override 
      public boolean onEditorAction(TextView v, int actionId, KeyEvent event) 
      { 
       String input; 
       if(actionId == EditorInfo.IME_ACTION_DONE) 
       { 
        input= v.getText().toString(); 
        Toast toast= Toast.makeText(LogIn.this,input, 
          Toast.LENGTH_LONG); 
        toast.setGravity(Gravity.CENTER, 0, 0); 
        toast.show(); 
        return true; 
       } 
       return false; 
      } 
     }); 
0

Ritorno true; dopo aver toccato ur caso e non sarà chiamato nuovamente

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 

       if (actionId == EditorInfo.IME_NULL) 
       { 
        Log.i("here","Add product "); 
        return true; //this does the trick 
       } 
       return false; 
      }  
1

Penso che se si torna vero, vuol dire che siete interessati nel resto degli eventi fino a raggiungere IME_ACTION_DONE. Quindi, se restituisci false, significa che non sei interessato agli eventi e che le altre visualizzazioni avranno quindi l'opportunità di gestirle. Dal momento che hai solo 1 vista, ti suggerisco di ignorare il controllo actionId e di restituire false ogni volta.

etMovieName = (EditText) view.findViewById(R.id.et_movie_name); 
etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
    @Override 
    public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) { 
     System.out.println("actionId= "+ actionId); 
     performSearch(); 
     return false; 
    } 
}); 

Altro situazione è se si ha una vista sovrapposti o una vista di pari livello, quindi è possibile utilizzare ActionID per passare informazioni in giro. In questa situazione, la restituzione di true ti consentirà di passare le informazioni all'altra vista. Se sei veramente interessato a caso/ActionID (ad esempio se si dispone di un'altra vista di pari livello), allora si può fare questo:

etMovieName = (EditText) view.findViewById(R.id.et_movie_name); 

etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE); 
etMovieName.setSingleLine(); 

etMovieName.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
    @Override 
    public boolean onEditorAction(TextView tv, int actionId, KeyEvent event) { 
     System.out.println("actionId= "+ actionId); 
     return performSearch();  } 
}); 

Avviso il valore ActionID è cambiato a 6 una volta ho aggiunto:

etMovieName.setImeOptions(EditorInfo.IME_ACTION_DONE); 
etMovieName.setSingleLine(); 
+1

Comportamento molto strano, ma sembra che tu abbia esattamente ragione. –

Problemi correlati