2010-09-12 14 views
20

Definí un campo EditText y deseo que se le informe cuando el usuario edite esos campos. Así que pensé: simple: agregué un OnKeyListener y así lo hice. Pero a pesar de que el campo de texto se edita (e incluso muestra el texto ingresado/modificado), no recibo ninguna devolución de llamada, es decir, el resultado de LOG no aparece.Android: ¿por qué mi OnKeyListener() no se llama?

TextView text = new TextView(this); 
    text.setText(...); 
    ... 
    text.setOnKeyListener(new OnKeyListener() 
    {       
     public boolean onKey(View v, int keyCode, KeyEvent event) { 
      TextView tv = (TextView)v; 
      CharSequence val = tv.getText(); 
      Log.v(TAG, "value: " + val); 
      // ... rest omitted for brevity 
     } 
    }); 

¿Alguna idea, por qué esa devolución de llamada nunca se llama?

Michael

PS .: Sigh! ¡Android está lleno de rarezas! Parece que casi nada de lo que toqué hasta ahora funcionó inmediatamente como uno esperaría. Y, lo creas o no, tengo MUCHA experiencia con GUIs, esp. en Java (AWT, Swing, SWT, lo que sea ...) ¡Pero Android es una bestia realmente dura!

+1

@Falmarri, ¿qué pasa con eso? Conceptualmente, getText devuelve una secuencia de caracteres, por lo que no hay nada de malo en tratar de almacenar el valor de retorno en una variable que sea de ese tipo. Y tienes que hacer ese reparto para usar el método getText. No puede simplemente cambiar el método onKey para tomar un TextView porque anula un método en OnKeyListener. (Podría decirse que debería haber una @Override en él, pero es bastante obvio en este caso.) – MatrixFrog

+1

@Falmari: obviamente no has programado para Android. También preferiría cadenas, pero Android devuelve CharSequence por todas partes en lugar de Strings, por lo que tienes que hacer moldes o Strings() con frecuencia. Y si un encabezado de método solo define una "Vista" pero usted sabe que es una Vista de texto y necesita uno de los métodos que solo proporciona TextView, ¿qué más puede hacer? ¿Tienes una mejor sugerencia? – mmo

Respuesta

18

¿Está utilizando el teclado virtual (ime) para escribir el texto de edición? Creo que onKeyListener solo se invoca con eventos del teclado de hardware. Es mejor que utilices TextWatcher si puedes. onKeyListener not working with soft keyboard (Android)

+0

Leo a través del apéndice referenciado y ese podría ser el problema. Por supuesto, nunca lo intenté con un teclado real (ya que mi dispositivo no tiene ninguno ...) y el teclado del emulador aparentemente no está activando esos eventos tampoco. Cambié a un TextWatcher como se sugirió y ¡eso funciona! ¡Gracias! – mmo

1

Usted dice que se trata de un texto de edición, pero su código se refiere a un TextView. Supongo que tienes un EditText en tus archivos XML de diseño, pero te estás refiriendo a este TextView recién creado en tu código, que de hecho ni siquiera está en la interfaz de usuario de la aplicación.

Si ya hay un EditText en su archivo XML de diseño, entonces necesita obtener un puntero al mismo en su código Java, probablemente usando el método findViewById(). Luego agrega tu OnKeyListener a ese EditText.

Definir su diseño en XML tiene mucho más sentido (al menos en muchos casos, si no en la mayoría) que definirlo un componente a la vez y luego agregar cada uno de esos componentes a la interfaz de usuario, como lo hace en Swing . Pero lleva un tiempo acostumbrarse, sin duda.

+0

tienes razón: el TextView es en realidad un EditText y no creado por "nuevo", sino que usa un inflador. Lo cambié aquí por brevedad. Pero todavía no recibo ningún onKey() - callbacks ... – mmo

+0

Podría estar equivocado, pero no creo que quiera usar un inflador aquí. Simplemente haz 'setContentView' y hace el inflado por ti. Mi suposición es que el mismo XML se está inflando dos veces, una a través de 'setContentView' y una a través de' LayoutInflater'.De modo que tiene dos copias del mismo diseño y el oyente se agrega al incorrecto. – MatrixFrog

+0

No, el problema no es que haya dos copias. Incluso elimino explícitamente a todos los niños antes de comenzar a agregar los propios. El problema parece ser el siguiente: ver el apéndice de Mayra. – mmo

7

Tuve exactamente el mismo problema, pero solo en 1 de mis aplicaciones de Android y nunca supe cuál era la diferencia.

Mi solución fue hacer lo que Mayra sugirió y agregar un TextWatcher para manejar los eventos TextChanged. Entonces funciona sin importar cómo se produce la entrada de texto.

editName.addTextChangedListener(new TextWatcher() { 
     public void afterTextChanged(Editable s) { 
      Button btnSave = (Button)findViewById(R.id.btnSaveToon); 
      if(s.length() > 0) 
       btnSave.setEnabled(true); 
      else 
       btnSave.setEnabled(false); 
     } 

     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
      // TODO Auto-generated method stub 
     } 

     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      // TODO Auto-generated method stub 
     } 

    }); 

funciona como un encanto en el emulador y en mi HTC Inspire

Cuestiones relacionadas