OnEditorActionListener llamado dos veces con el mismo eventTime en el teclado SenseUI

En un solo teléfono en el que estoy probando (HTC Incredible, Android 2.2, Software 3.21.605.1), estoy experimentando el siguiente comportamiento.

El controlador de eventos onEditorAction se llama dos veces (inmediatamente) cuando se presiona la tecla Intro del teclado Sense UI.

El KeyEvent.getEventTime () es el mismo para las dos veces que se llama al evento, lo que me lleva a este 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; } } }); [...] } 

El EditText se define como:

 <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" /> 

En todos los otros dispositivos en los que he probado, el botón de acción está correctamente etiquetado como "Siguiente" y el evento solo se llama una vez cuando se presiona ese botón.

¿Es esto un error en el teclado de Sense UI, o estoy haciendo algo incorrecto?

Gracias por cualquier ayuda.


Actualizado – gracias a las respuestas dadas, he establecido sobre lo siguiente como mis cheques. Esto funciona bien en los dos teléfonos que tengo disponible para probar (Sense UI y Cyanogenmod CM7)

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

Como dijo mitch, tienes que comprobar la acción del evento:

 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (event.getAction() != KeyEvent.ACTION_DOWN) return false; // do your stuff return true; } 

Este fragmento funciona tanto en la interfaz de usuario de Sense como en el emulador.

 (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; } }); 

Creo que si devuelves true, significa que estás interesado en el resto de los eventos hasta que llegue a IME_ACTION_DONE. Por lo tanto, si devuelves un error, significa que no estás interesado en los eventos y que otros puntos de vista tendrán la oportunidad de manejarlo. Puesto que solo tienes 1 vista, te sugiero que ignores el cheque de actionId y simplemente devuelves false cada vez.

 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; } }); 

Otra situación es si tienes vistas superpuestas o una vista de hermanos, entonces puedes usar actionId para pasar información. En esta situación, devolver verdadero le permitirá pasar información a la otra vista. Si realmente está interesado en el evento / acciónId (por ejemplo, si tiene otra vista de hermanos), puede hacer esto:

 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(); } }); 

Observe que el valor de actionId ha cambiado a 6 una vez que agregué:

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

En vez de enviar una acción del ime y null como acontecimiento, envía un acontecimiento del tacto así que si su no conseguir la acción correcta usted puede comprobar el acontecimiento para el action_up o el action_down

Devuelve verdadero; Después de manejar su caso y no será llamado de nuevo

 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; } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.