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.

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top