TextWatcher: cos'è, interfaccia TextWatcher e implementazione in Android

Autore: IT Sectr Pubblicato: 2026-07-08 Tempo di lettura: 6 min

TextWatcher è un'interfaccia Android che consente di tracciare le modifiche al testo in EditText e altri TextView in tempo reale. Lo sviluppatore riceve notifiche in tre fasi: prima della modifica, durante la modifica e dopo la modifica del contenuto testuale. Secondo Android Developers, 2026, TextWatcher viene utilizzato nella maggior parte delle applicazioni per la validazione dell'input, il conteggio dei caratteri, l'implementazione della ricerca con completamento automatico e la formattazione dinamica del testo. L'interfaccia è indispensabile nei moduli in cui è richiesta una reazione immediata a ogni pressione di tasto.

Punti chiave

  • TextWatcher è un'interfaccia integrata dell'Android SDK per ascoltare le modifiche al testo in TextView e EditText.
  • L'interfaccia contiene tre metodi: beforeTextChanged, onTextChanged e afterTextChanged, ciascuno responsabile della propria fase di modifica.
  • Il metodo afterTextChanged è il più comodo per validare il campo dopo che l'utente ha completato l'input.
  • Chiamata ricorsiva è un errore comune: modificare il testo all'interno di TextWatcher porta a un ciclo infinito.
  • TextWatcher viene utilizzato nei campi di ricerca, validazione dei moduli, conteggio caratteri e formattazione automatica del numero di telefono.

Cos'è TextWatcher e perché serve?

TextWatcher è un'interfaccia del pacchetto android.text che notifica all'applicazione le modifiche al testo negli oggetti Editable. A ogni inserimento, eliminazione o sostituzione di carattere, TextWatcher chiama sequenzialmente tre metodi, trasmettendo informazioni sulla posizione delle modifiche. Ciò consente allo sviluppatore di reagire istantaneamente alle azioni dell'utente — senza pulsanti o trigger aggiuntivi.

I principali casi d'uso includono la validazione dei campi in tempo reale: verificare l'email durante la digitazione di ogni carattere, contare i caratteri rimanenti in un campo con limite di lunghezza, implementare la ricerca con richiesta differita tramite debounce. TextWatcher viene utilizzato anche per formattare l'input — ad esempio, l'inserimento automatico di spazi in un numero di telefono o l'aggiunta di una maschera per una data.

Secondo Android Developers, TextWatcher è presente nel 70% delle applicazioni che lavorano con moduli. Librerie come Material Design Components e TextInputEditText usano TextWatcher internamente per gestire gli stati di errore e visualizzare i contatori. Comprendere il funzionamento di questa interfaccia è essenziale per ogni sviluppatore Android.

Come funziona l'interfaccia TextWatcher

TextWatcher si collega a qualsiasi oggetto TextView o EditText tramite il metodo addTextChangedListener. Quando l'utente digita o elimina un carattere, Android chiama prima beforeTextChanged, poi onTextChanged e infine afterTextChanged. I parametri di ciascun metodo contengono dati sull'intervallo modificato: posizione iniziale, numero di caratteri eliminati e numero di caratteri aggiunti.

È importante capire che dopo aver chiamato afterTextChanged, l'oggetto Editable contiene già il valore corrente. Pertanto, è conveniente verificare il testo finale del campo in afterTextChanged. Prima di quel momento, i dati non sono ancora completamente aggiornati. Gli sviluppatori spesso confondono lo scopo dei metodi e usano onTextChanged per la validazione finale, mentre la scelta corretta è afterTextChanged.

Particolarità della chiamata ai metodi

A ogni inserimento, sostituzione o eliminazione di carattere, la catena di chiamate è garantita per essere eseguita completamente. Tuttavia, se il testo viene modificato all'interno di afterTextChanged (tramite clear, append, insert), TextWatcher si attiverà in modo ricorsivo. Questa è la causa più comune di StackOverflowError nei moduli Android. Per prevenire la ricorsione, si utilizza un flag di blocco.

Tre metodi di TextWatcher: beforeTextChanged, onTextChanged, afterTextChanged

Ciascuno dei tre metodi svolge il proprio ruolo nel ciclo di vita della modifica del testo. Il metodo beforeTextChanged(CharSequence s, int start, int count, int after) viene chiamato prima dell'applicazione delle modifiche. Trasmette lo stato corrente della stringa, la posizione iniziale della modifica, il numero di caratteri da eliminare e il numero da aggiungere. Qui puoi salvare il valore precedente o verificare le condizioni prima della modifica.

Il metodo onTextChanged viene chiamato durante la modifica, quando i caratteri sono già stati rimossi ma quelli nuovi non sono ancora stati inseriti. Parametri: il testo dopo l'eliminazione, posizione iniziale, numero di caratteri eliminati e numero di caratteri aggiunti. Questo metodo è comodo per animazioni o registrazione, ma non per lavorare con il testo finale effettivo — non è ancora stato assemblato.

Il metodo afterTextChanged è il più richiesto. Riceve un oggetto Editable e viene chiamato dopo che le modifiche sono state completamente applicate. In questo metodo puoi leggere il valore finale del campo, eseguire la validazione, aggiornare l'UI e modificare il testo (con cautela a causa della ricorsione).

Esempio di implementazione di TextWatcher per il conteggio caratteri

Un esempio pratico è un contatore di caratteri per un campo di input che si aggiorna a ogni modifica del testo. Tale elemento si trova spesso nei moduli di feedback, nei post e nei messaggi con limite di lunghezza. L'implementazione tramite TextWatcher richiede poche righe e non necessita di librerie di terze parti.

kotlin
val editText = findViewById<EditText>(R.id.edit_text)
val counterText = findViewById<TextView>(R.id.counter)

editText.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(
        s: CharSequence?, start: Int,
        count: Int, after: Int
    ) {}

    override fun onTextChanged(
        s: CharSequence?, start: Int,
        before: Int, count: Int
    ) {}

    override fun afterTextChanged(s: Editable?) {
        val len = s?.length ?: 0
        counterText.text = "$len / 200"
    }
})

Nell'esempio, il metodo afterTextChanged riceve il contenuto corrente del campo tramite il parametro s di tipo Editable. La lunghezza del testo viene aggiornata in un TextView separato. In questo caso, viene modificato solo counterText, non l'EditText stesso, quindi non si verifica alcun ciclo. Per un limite di 200 caratteri, puoi bloccare ulteriormente l'input dopo il superamento.

I metodi beforeTextChanged e onTextChanged rimangono vuoti, poiché lo stato finale è sufficiente per il conteggio della lunghezza. Se è necessario registrare ogni modifica, è possibile aggiungere codice in onTextChanged. Questa flessibilità rende TextWatcher uno strumento universale per qualsiasi scenario di input di testo.

TextWatcher per la validazione dei campi in tempo reale

La validazione in tempo reale migliora significativamente l'UX: l'utente vede un errore immediatamente dopo aver inserito un valore errato, anziché dopo aver cliccato il pulsante di invio. TextWatcher consente la verifica istantanea di email, password, numero di telefono e altri campi. Il risultato viene visualizzato tramite setError sull'EditText o tramite un TextView separato con un messaggio di errore.

kotlin
fun validateEmail(emailEditText: EditText) {
    emailEditText.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            val email = s?.toString () ?: ""
            if (email.isNotBlank() &&
                !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
                emailEditText.error = "Invalid email address"
            } else {
                emailEditText.error = null
            }
        }

        override fun beforeTextChanged(...) {}
        override fun onTextChanged(...) {}
    })
}

L'esempio utilizza il Patterns.EMAIL_ADDRESS integrato dell'Android SDK per verificare l'email. Se il testo non è vuoto e non corrisponde al modello, viene impostato un errore sul campo tramite la proprietà error. Quando l'input è corretto, l'errore viene cancellato. È importante non eseguire la validazione su un campo vuoto — l'utente potrebbe non aver ancora iniziato a digitare e un messaggio di errore sarebbe prematuro.

Per password e numeri di telefono, si utilizzano espressioni regolari personalizzate o librerie specializzate. Ad esempio, per verificare la complessità della password, puoi contare il numero di cifre, lettere maiuscole e minuscole. TextWatcher consente di aggiornare l'indicatore di forza della password in tempo reale, il che influisce positivamente sulla conversione di registrazione.

Errori comuni quando si lavora con TextWatcher

Il primo e più critico errore è la chiamata ricorsiva. Se modifichi il testo dello stesso EditText all'interno di afterTextChanged (tramite s.clear(), s.append() o s.insert()), TextWatcher si attiverà di nuovo. Questo crea un ciclo infinito che termina con StackOverflowError. La soluzione è usare un flag di blocco isUpdating o verificare se il testo è effettivamente cambiato.

Il secondo problema comune è la perdita di memoria. TextWatcher mantiene un riferimento implicito all'Activity o al Fragment tramite una classe anonima. Se il listener non viene rimosso alla distruzione della View, il garbage collector non può liberare la memoria. La soluzione è utilizzare componenti del ciclo di vita o chiamare esplicitamente removeTextChangedListener in onDestroyView.

Il terzo errore è usare il metodo sbagliato. Alcuni sviluppatori eseguono la validazione finale in onTextChanged, senza attendere afterTextChanged. In onTextChanged, il testo non è ancora completamente aggiornato e la lettura del valore finale può restituire dati errati. L'approccio corretto è che tutta la logica di lettura e verifica del testo finale dovrebbe essere in afterTextChanged.

MetodoMomento della chiamataScopoPuò leggere il testo finale?
beforeTextChangedPrima della modificaSalvare lo stato precedente
onTextChangedDurante la modificaRegistrazione, animazioneNo
afterTextChangedDopo la modificaValidazione, conteggio, aggiornamento UI

Il quarto errore è l'aggiunta multipla di TextWatcher. Se addTextChangedListener viene chiamato più volte per lo stesso EditText, tutti i listener elaboreranno la stessa modifica. Nei moduli con aggiunta dinamica di View, ciò porta a controlli duplicati e comportamento imprevedibile. Verifica sempre se il listener è già stato aggiunto o utilizza una singola istanza.

Domande frequenti

Qual è la differenza tra onTextChanged e afterTextChanged?

OnTextChanged viene chiamato nel momento della modifica del testo, quando i nuovi caratteri non sono ancora stati aggiunti. Questo metodo è adatto per animazioni e registrazione. AfterTextChanged viene chiamato dopo la completa applicazione delle modifiche e fornisce accesso al testo finale tramite il parametro Editable. Per validazione e lettura dei valori, usa afterTextChanged.

Come evitare la chiamata ricorsiva di TextWatcher?

Usa un flag di blocco di tipo Boolean, impostato a true prima di modificare il testo all'interno di afterTextChanged. Controlla il flag all'inizio del metodo: se true — esci. In alternativa, confronta i valori vecchio e nuovo e modifica il testo solo quando c'è una differenza effettiva.

È necessario rimuovere TextWatcher quando si distrugge un'Activity?

Sì, assolutamente. La classe anonima TextWatcher mantiene un riferimento all'Activity tramite una chiusura. Se il listener non viene rimosso, l'Activity non può essere raccolta dal garbage collector. Chiama sempre removeTextChangedListener in onDestroyView per Fragment o onDestroy per Activity.

Si può usare TextWatcher in RecyclerView?

Sì, ma con attenzione. In RecyclerView, i ViewHolder vengono riutilizzati e un TextWatcher da una posizione precedente può rimanere attivo. Rimuovi sempre il vecchio TextWatcher prima di impostarne uno nuovo nel metodo onBindViewHolder. Usa tag o campi separati del ViewHolder per memorizzare il riferimento al listener.

Quale metodo è migliore per la ricerca con completamento automatico?

Per un campo di ricerca, usa afterTextChanged in combinazione con debounce (ritardo). Implementa un timer di 300-500 ms che si azzera a ogni nuova modifica del testo. Ciò impedisce l'invio di una richiesta al server a ogni pressione di tasto e riduce il carico dell'API.

Riepilogo

  • TextWatcher è un'interfaccia Android per tracciare le modifiche al testo in EditText e TextView, che implementa tre metodi di callback.
  • Il metodo afterTextChanged è la scelta ottimale per la validazione e la lettura del testo finale dopo le modifiche.
  • Chiamata ricorsiva è il pericolo principale di TextWatcher, prevenuto da un flag di blocco.
  • La rimozione del listener è obbligatoria per prevenire perdite di memoria quando si distrugge un'Activity o un Fragment.
  • La validazione in tempo reale con TextWatcher migliora l'UX e consente di mostrare gli errori istantaneamente.
  • Debounce è necessario quando si implementa la ricerca e il completamento automatico per ridurre il carico del server.
  • Scegliere il metodo corretto è la chiave per un funzionamento stabile: beforeTextChanged per salvare lo stato, onTextChanged per i log, afterTextChanged per il controllo finale.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche