Come aggiornare lo stesso EditText utilizzando TextWatcher?
-
14-11-2019 - |
Domanda
Nella mia applicazione Android devo implementare un'interfaccia TextWatcher da implementare onTextChanged
.Il problema che ho è che voglio aggiornare lo stesso EditText con qualche stringa in più.Quando provo a farlo il programma termina.
final EditText ET = (EditText) findViewById(R.id.editText1);
ET.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
try
{
ET.setText("***"+ s.toString());
ET.setSelection(s.length());
}
catch(Exception e)
{
Log.v("State", e.getMessage());
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
@Override
public void afterTextChanged(Editable s)
{
}
});
Il mio programma termina e anche io provo a rilevare l'eccezione come nel mio codice, tuttavia termina.Qualcuno ha qualche idea del perché questo accada e di come posso raggiungere questo obiettivo?Grazie.
Soluzione
Il contenuto del TextView
È non modificabile sul onTextChanged
evento.
Invece, devi gestire il afterTextChanged
evento per poter apportare modifiche al testo.
Per una spiegazione più approfondita vedere: Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
Nota:Errore onTextChanged
Ovviamente, stai causando un ciclo infinito modificando continuamente il file testo SU afterTextChanged
evento.
Da il rif:
vuoto astratto pubblico afterTextChanged (modificabili)
Questo metodo è chiamato per avvisarti che, da qualche parte all'interno di S, il testo è stato modificato.È legittimo apportare ulteriori modifiche a S da questo callback, ma fai attenzione a non metterti in un ciclo infinito, perché eventuali modifiche che apportate causerà nuovamente questo metodo in modo ricorsivo....
Suggerimento 1:se puoi, controlla se il
s
È Già quello che vuoi quando l'evento viene attivato.@Override public void afterTextChanged(Editable s) { if( !s.equalsIngoreCase("smth defined previously")) s = "smth defined previously"; }
- Suggerimento 2:Se hai bisogno di fare cose più complesse (formattazione, convalida) puoi usare un
synchronized
metodo come in questo post.
Nota 2 :Formattare l'input come parzialmente nascosto con N stelle fino all'ultimo 4 caratteri (****quattro)
Puoi usare qualcosa di simile in suggerimento 1:
@Override
public void afterTextChanged(Editable s)
{
String sText = ET.getText().toString()
if( !isFormatted(sText))
s = format(sText);
}
bool isFormatted(String s)
{
//check if s is already formatted
}
string format(String s)
{
//format s & return
}
Altri suggerimenti
Risposta tardiva, se qualcuno sembra questo è come l'ho fatto.
- .
- Imposta AddTextChangeDListener Inizialmente
- in una delle chiamate (Dì OnTextChanged ()) Rimuovere AddTextChangeDListener
- Ancora interessato a ricevere aggiornamenti aggiungilo di nuovo.
Ecco il codice.
.editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { Log.d("log", "before"); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { Log.d("log", "after"); editText.removeTextChangedListener(this); ediText.setText("text you wanted to put"); editText.addTextChangedListener(this); } @Override public void afterTextChanged(Editable s) { } });
to supplemento La risposta di Zortkun (dove il codice di esempio è abbastanza rotto), questo è il modo in cui useresti afterTextChanged()
a Aggiorna lo stesso EditText
:
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
if (!editable.toString().startsWith("***")) {
editable.insert(0, "***");
}
}
});
.
Prendi familiarità con il Editable
Interfaccia per conoscere altre operazioni Oltre a insert()
.
Nota che è facile finire in un ciclo infinito (le modifiche che si eseguono di nuovo afterTextChanged()
), in modo da tipicamente fare le modifiche all'interno di una condizione IF , come sopra. come afterTextChanged()
javadocs Dì:
.è legittimo apportare ulteriori modifiche a S da questo callback, ma Fai attenzione a non prenderti in un ciclo infinito, perché qualcuno le modifiche apportate causerà di nuovo questo metodo ricorsivamente.
Ecco uno snippet che ha funzionato per me
etPhoneNumber.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
if (!s.toString().equals(Utils.getFormattedNumber(s.toString()))) {
s.replace(0, s.length(), Utils.getFormattedNumber(s.toString()));
}
}
});
.
Dove Utils.getFormattedPhoneNumber()
è il tuo metodo che restituisce un numero formattato