2012-02-27 21 views
5

que necesito para detectar cambios en el texto en un EditarTexto. Intenté TextWatcher, pero no funciona de la manera que esperaría. Tome el método OnTextChanged:detectar cambios en EditarTexto (TextWatcher ineficaz)

public void onTextChanged(CharSequence s, int start, int before, int count)

Digamos que tiene el texto "John" en ya en el EditarTexto. Si presiona otra tecla, "e", s será "Johne", start será 0, before habrá 4, y count habrá 5. La forma en que sería de esperar que este método funcione sería la diferencia entre lo que el EditarTexto previamente era, y en lo que se convertirá.

Por lo tanto, sería de esperar:

s = "Johne" 
start = 4 // inserting character at index = 4 
before = 0 // adding a character, so there was nothing there before 
count = 1 // inserting one character 

tengo que ser capaz de detectar cambios individuales cada vez que se pulsa una tecla. Así que si tengo texto "John", necesito saber "e" se añadió al índice 4. Si retroceso "e", lo que necesito saber "e" fue eliminado del índice 4. Si pongo el cursor después de "J "y retroceso, necesito saber que" J "se eliminó del índice 0. Si pongo una" G "donde estaba" J ", quiero saber que" G "reemplazó a" J "en el índice 0.

Cómo puedo lograr esto? No puedo pensar en una manera confiable de hacer esto.

+0

onKeyListener intento de EditarTexto –

+0

¿Qué hay de pegar desde el portapapeles? –

+0

Otro problema que tengo es que digo que tengo seleccionado un rango de texto. En cualquiera de los métodos de TextWatcher, getSelectionStart y End son siempre del mismo índice, independientemente de si tengo texto seleccionado o no. –

Respuesta

9

Utilice un textwatcher y haga lo mismo diff. almacene el texto anterior dentro del observador y luego compare el texto anterior con la secuencia que obtenga en TextChanged. Dado que onTextChanged se activa después de cada carácter, usted conoce su texto anterior y el texto dado diferirá, como máximo, de una letra, lo que debería facilitar la tarea de averiguar qué letra se agregó o dónde se eliminó. es decir:

new TextWatcher(){ 
    String previousText = theEditText.getText(); 

    @Override 
    onTextChanged(CharSequence s, int start, int before, int count){ 
     compare(s, previousText); //compare and do whatever you need to do 
     previousText = s; 
    } 

    ... 
} 
+0

Es una sugerencia en la que he pensado, y ciertamente viable, pero esperaba un "¡listo!" método, que puede no existir. El único problema con su enfoque es que el texto puede diferir en más de 1 letra (rango de selección, pegado desde el portapapeles). –

+1

Es cierto, pero en el que los índices de puntos tienen poco significado (lo que sucede si pega una palabra antes de que el texto actual por ejemplo?) Y aún así todavía se puede hacer lo mismo diff. No creo que haya soluciones integradas para lo que estás tratando de hacer. –

+0

Bastante justo. Terminé haciendo lo que dijiste y básicamente implementé mi propio TextWatcher y pasé los valores que esperaba. No es 100% infalible pero es bastante cercano. –

0

Debe almacenar y actualizar la CharSequence anterior cada vez que se cambia el texto. Puede hacerlo implementando el TextWatcher.

Ejemplo:

final CharSequence[] previousText = {""}; 
editText.addTextChangedListener(new TextWatcher() 
{ 
    @Override 
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) 
    { 
    } 

    @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) 
    { 
     if(i1 > 0) 
     { 
      System.out.println("Removed Chars Positions & Text:"); 
      for(int index = 0; index < i1; index++) 
      { 
       System.out.print((i + index) + " : " + previousText[0].charAt(i + index)+", "); 
      } 
     } 
     if(i2 > 0) 
     { 
      System.out.println("Inserted Chars Positions & Text:"); 
      for(int index = 0; index < i2; index++) 
      { 
       System.out.print((index + i) + " : " + charSequence.charAt(i + index)+", "); 
      } 
      System.out.print("\n"); 
     } 
     previousText[0] = charSequence.toString();//update reference 
    } 

    @Override public void afterTextChanged(Editable editable) 
    { 
    } 
}); 
Cuestiones relacionadas