2010-11-03 15 views
24

En solo un teléfono que estoy probando (HTC Incredible, Android 2.2, Software 3.21.605.1), estoy experimentando el siguiente comportamiento.OnEditorActionListener llamado dos veces con el mismo eventoTiempo en el teclado SenseUI

El controlador de eventos onEditorAction se llama dos veces (inmediatamente) cuando se presiona la tecla Entrar en el teclado de la interfaz de usuario de Sense.

El KeyEvent.getEventTime() es el mismo para las dos veces el evento se llama, que me lleva a esta solución alternativa:

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 EditarTexto 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 demás dispositivos en los que he probado, el botón de acción está etiquetado correctamente como "Siguiente" y el evento solo se llama una sola vez cuando se presiona ese botón.

¿Esto es un error en el teclado de Sense UI, o estoy haciendo algo incorrectamente?

Gracias por cualquier ayuda.


Actualizado - gracias a las respuestas dadas, he establecido lo siguiente como mis cheques. Esto funciona bien en ambos de los teléfonos que tiene disponible para la prueba (interfaz de usuario Sense 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; 
      } 
+2

Sin respuesta para usted Tengo miedo, solo quería decir que esta edición me ha afectado hoy. Nunca antes había visto el teclado HTC Sense ... ¡Uf!¿Y cómo se salieron con la tarea de ignorar el indicador textNoSuggestions? Hace que mi interfaz de usuario sea un poco sucky, los descompone. –

+0

Me he dado cuenta de que muchas aplicaciones no funcionan del todo bien, ya que su teclado no implementa el botón predeterminado (siempre es "Enter"). Esto incluye las aplicaciones proporcionadas por Google (incluido, creo, el proceso de registro inicial). Parece una gran cosa para HTC pasar por alto. Es una pena, porque en realidad me gusta más SenseUI que Motoblur. Gracias por la confirmación. – mbafford

Respuesta

26

Como dijo Mitch, usted tiene 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 de código funciona tanto en la interfaz de usuario Sense y el emulador.

+2

Esto parece ser casi la respuesta, aunque en mi otro teléfono (ejecutando CyanogenMod CM7), "evento" es nulo cuando presiono "Siguiente" en el teclado, así que también debo verificarlo. – mbafford

+1

También he agregado un "if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED) return false;" al método. – AlexVogel

0

en lugar de enviar una acción IME y nulo como un evento, envía un evento de contacto así que si tu no conseguir el acción correcta se puede comprobar el caso de action_up o action_down

+1

No entiendo lo que dice aquí. ¿Hay algún evento que funcione correctamente en la interfaz de usuario de Sense de HTC y en otros teclados que implementen correctamente la acción predeterminada? – 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

Return true; después de manipular ur caso y que 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; 
      }  
1

Creo que si devuelve cierto, significa que usted está interesado en el resto de los acontecimientos hasta que alcanza IME_ACTION_DONE. Entonces, si devuelve falso, significa que no está interesado en los eventos y que otros puntos de vista tendrán la oportunidad de manejarlo. Como solo tiene 1 vista, le sugiero que simplemente ignore la verificación actionId y simplemente devuelva 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 que si tienes vistas superpuestas o una vista de hermanos, entonces se puede utilizar para pasar información ActionID alrededor. En esta situación, devolver verdadero le permitirá pasar información a la otra vista. Si realmente está interesado en el evento/ActionID (por ejemplo, si tiene otra vista hermanos), entonces usted 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();  } 
}); 

Aviso el valor ActionID ha cambiado a 6 una vez añadí:

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

Comportamiento muy extraño, pero parece que tienes razón. –

Cuestiones relacionadas