Rileva le modifiche in EditText (Inefficace TextWatcher)
-
13-11-2019 - |
Domanda
Devo rilevare le modifiche al testo in un EditText. Ho provato TextWatcher, ma non funziona in un modo che mi aspetterei. Prendi il metodo OnTextChanged:
public void onTextChanged( CharSequence s, int start, int before, int count )
Supponiamo che io abbia il testo "John" già in EditText. Se premere un altro tasto, "E", s
sarà "Johne", start
sarà 0, before
sarà 4 e count
Sarà 5. Il modo in cui mi aspetterei che questo metodo funzioni sarebbe la differenza tra ciò che era in precedenza EditText e ciò che sta per diventare.
Quindi mi aspetterei:
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
Devo essere in grado di rilevare le singole modifiche ogni volta che viene premuto un tasto. Quindi, se ho un testo "John", devo sapere "e" è stato aggiunto all'indice 4. Se ho backspace "e", devo sapere "e" è stato rimosso dall'indice 4. "E backspace, devo sapere" J "è stato rimosso dall'indice 0. Se metto una" g "dove era" J ", voglio sapere" g "sostituito" J "all'indice 0.
Come posso raggiungere questo obiettivo? Non riesco a pensare a un modo affidabile per farlo.
Soluzione
Usa un guardiano di testo e fai il differenziale da solo. Memorizza il testo precedente all'interno dell'osservatore, quindi confronta il testo precedente con qualsiasi sequenza che si ottiene. Poiché OnTextChanged viene licenziato dopo ogni personaggio, conosci il tuo testo precedente e il testo dato differirà al massimo una lettera, il che dovrebbe rendere semplice capire quale lettera è stata aggiunta o rimossa dove. cioè:
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;
}
...
}
Altri suggerimenti
L'approccio migliore che puoi seguire per identificare le modifiche al testo.
var previousText = ""
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
previousText = s.toString()
}
override fun onTextChanged(newText: CharSequence?, start: Int, before: Int, count: Int) {
val position = start + before ;
if(newText!!.length > previousText.length){ //Character Added
Log.i("Added Character", " ${newText[position]} ")
Log.i("At Position", " $position ")
} else { //Character Removed
Log.i("Removed Character", " ${previousText[position-1]} ")
Log.i("From Position", " ${position-1} ")
}
}
override fun afterTextChanged(finalText: Editable?) { }
È necessario archiviare e aggiornare la charsequence precedente ogni volta che il testo viene modificato. Puoi farlo implementando il TextWatcher.
Esempio:
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)
{
}
});