TextWatcher: ce este, interfața TextWatcher și implementarea în Android

Autor: IT Sectr Publicat: 2026-07-08 Timp de citire: 6 min

TextWatcher este o interfață Android care permite monitorizarea modificărilor textului în EditText și alte TextView în timp real. Dezvoltatorul primește notificări în trei etape: înainte de modificare, în timpul modificării și după modificarea conținutului textului. Conform Android Developers, 2026, TextWatcher este utilizat în majoritatea aplicațiilor pentru validarea intrării, numărarea caracterelor, implementarea căutării cu autocompletare și formatarea dinamică a textului. Interfața este indispensabilă în formularele care necesită reacție imediată la fiecare apăsare de tastă.

Principalele puncte

  • TextWatcher — interfață încorporată Android SDK pentru ascultarea modificărilor textului în TextView și EditText.
  • Interfața conține trei metode: beforeTextChanged, onTextChanged și afterTextChanged, fiecare responsabilă pentru etapa sa de modificare.
  • Metoda afterTextChanged este cea mai convenabilă pentru validarea câmpului după finalizarea introducerii de către utilizator.
  • Apelul recursiv — eroare frecventă: modificarea textului în interiorul TextWatcher duce la o buclă infinită.
  • TextWatcher este utilizat în câmpurile de căutare, validarea formularelor, numărarea caracterelor și formatarea automată a numărului de telefon.

Ce este TextWatcher și la ce servește?

TextWatcher este o interfață din pachetul android.text care notifică aplicația despre modificările textului în obiectele Editable. La fiecare introducere, ștergere sau înlocuire a unui caracter, TextWatcher apelează secvențial trei metode, transmitând informații despre poziția modificărilor. Acest lucru permite dezvoltatorului să reacționeze instantaneu la acțiunile utilizatorului — fără butoane suplimentare sau declanșatoare.

Scenariile principale de utilizare includ validarea câmpurilor în timp real: verificarea emailului la introducerea fiecărui caracter, numărarea caracterelor rămase într-un câmp cu limită de lungime, implementarea căutării cu trimiterea întârziată a cererii prin debounce. De asemenea, TextWatcher este utilizat pentru formatarea intrării — de exemplu, inserarea automată a spațiilor în numărul de telefon sau adăugarea unei măști pentru dată.

Conform Android Developers, TextWatcher este prezent în 70% din aplicațiile care lucrează cu formulare. Biblioteci precum Material Design Components și TextInputEditText folosesc TextWatcher intern pentru gestionarea stării de eroare și afișarea contoarelor. Înțelegerea funcționării acestei interfețe este necesară pentru fiecare dezvoltator Android.

Cum funcționează interfața TextWatcher

TextWatcher se conectează la orice obiect TextView sau EditText prin metoda addTextChangedListener. Când utilizatorul introduce sau șterge un caracter, Android apelează mai întâi beforeTextChanged, apoi onTextChanged și în final afterTextChanged. În parametrii fiecărei metode sunt transmise date despre intervalul modificat: poziția de start, numărul de caractere șterse și numărul de caractere adăugate.

Este important de înțeles că după apelarea afterTextChanged, obiectul Editable conține deja valoarea actuală. De aceea, în afterTextChanged este convenabil să verifici textul final al câmpului. Până în acest moment, datele nu sunt încă complet actualizate. Dezvoltătorii confundă adesea destinația metodelor și folosesc onTextChanged pentru validarea finală, deși alegerea corectă este afterTextChanged.

Particularități ale apelării metodelor

La fiecare inserare, înlocuire sau ștergere a unui caracter, lanțul de apeluri este garantat să se execute complet. Totuși, dacă în interiorul afterTextChanged se modifică textul (prin clear, append, insert), TextWatcher se va declanșa recursiv. Aceasta este cea mai frecventă cauză a StackOverflowError în formularele Android. Pentru prevenirea recursivității se folosește un flag de blocare.

Cele trei metode TextWatcher: beforeTextChanged, onTextChanged, afterTextChanged

Fiecare dintre cele trei metode joacă un rol în ciclul de viață al modificării textului. Metoda beforeTextChanged(CharSequence s, int start, int count, int after) este apelată înainte de aplicarea modificărilor. Transmite starea curentă a șirului, poziția de început a modificării, numărul de caractere șterse și numărul de caractere adăugate. Aici poți salva valoarea anterioară sau verifica condițiile înainte de modificare.

Metoda onTextChanged este apelată în timpul modificării, când caracterele au fost deja șterse dar cele noi nu au fost încă inserate. Parametri: textul după ștergere, poziția de start, numărul de caractere șterse și numărul de caractere adăugate. Această metodă este utilă pentru animație sau logare, dar nu pentru lucrul cu textul final actual — acesta nu este încă complet.

Metoda afterTextChanged — cea mai solicitată. Primește un obiect Editable și este apelată după ce modificările au fost complet aplicate. În această metodă poți citi valoarea finală a câmpului, efectua validarea, actualiza UI și modifica textul (cu prudență din cauza recursivității).

Exemplu de implementare TextWatcher pentru numărarea caracterelor

Exemplu practic — contor de caractere pentru un câmp de introducere care se actualizează la fiecare modificare a textului. Un astfel de element apare adesea în formularele de contact, postări și mesaje cu limită de lungime. Implementarea prin TextWatcher necesită câteva rânduri și nu necesită biblioteci externe.

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"
    }
})

În exemplu, metoda afterTextChanged primește conținutul curent al câmpului prin parametrul s de tip Editable. Lungimea textului este actualizată într-un TextView separat. Pentru a evita recursivitatea în acest caz, se modifică doar counterText, nu și EditText-ul însuși, deci nu apare nicio buclă. La o limită de 200 de caractere, se poate bloca suplimentar introducerea după depășire.

Metodele beforeTextChanged și onTextChanged rămân goale, deoarece pentru numărarea lungimii este suficientă starea finală. Dacă este necesară logarea fiecărei modificări, codul poate fi adăugat în onTextChanged. O astfel de flexibilitate face din TextWatcher un instrument universal pentru orice scenariu de lucru cu introducerea textului.

TextWatcher pentru validarea câmpurilor în timp real

Validarea în timp real îmbunătățește semnificativ UX: utilizatorul vede eroarea imediat după introducerea unei valori incorecte, nu după apăsarea butonului de trimitere. TextWatcher permite verificarea instantanee a emailului, parolei, numărului de telefon și a altor câmpuri. Rezultatul este afișat prin setError pe EditText sau printr-un TextView separat cu mesaj de eroare.

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(...) {}
    })
}

În exemplu este folosit Patterns.EMAIL_ADDRESS încorporat din Android SDK pentru verificarea emailului. Dacă textul nu este gol și nu se potrivește cu șablonul, câmpului i se atribuie o eroare prin proprietatea error. La introducerea corectă, eroarea este ștearsă. Este important să nu rulezi validarea pe un câmp gol — utilizatorul poate să nu fi început încă introducerea, iar mesajul de eroare ar fi prematur.

Pentru parole și numere de telefon se folosesc expresii regulate personalizate sau biblioteci specializate. De exemplu, pentru verificarea complexității parolei se poate număra numărul de cifre, litere mari și mici. TextWatcher permite actualizarea indicatorului de complexitate a parolei în timp real, ceea ce influențează pozitiv conversia înregistrării.

Erori tipice la lucrul cu TextWatcher

Prima și cea mai critică eroare — apelul recursiv. Dacă în interiorul afterTextChanged se modifică textul aceluiași EditText (prin s.clear(), s.append() sau s.insert()), TextWatcher se va declanșa din nou. Aceasta creează o buclă infinită care duce la StackOverflowError. Soluția — utilizarea unui flag de blocare isUpdating sau verificarea dacă textul s-a schimbat efectiv.

A doua problemă frecventă — scurgerea de memorie. TextWatcher conține o referință implicită la Activity sau Fragment printr-o clasă anonimă. Dacă listenerul nu este eliminat la distrugerea View-ului, garbage collector nu poate elibera memoria. Soluția — utilizarea componentelor de ciclu de viață sau apelarea explicită a removeTextChangedListener în onDestroyView.

A treia eroare — utilizarea metodei greșite. Unii dezvoltatori efectuează validarea finală în onTextChanged, fără a aștepta afterTextChanged. În onTextChanged textul nu este încă complet actualizat, iar citirea valorii finale poate returna date incorecte. Abordarea corectă — plasarea întregii logici de citire și verificare a textului final în afterTextChanged.

MetodaMomentul apelăriiDestinațiaSe poate citi textul final?
beforeTextChangedÎnainte de modificareSalvarea stării anterioareDa
onTextChangedÎn timpul modificăriiLogare, animațieNu
afterTextChangedDupă modificareValidare, numărare, actualizare UIDa

A patra eroare — adăugarea multiplă a TextWatcher. Dacă addTextChangedListener a fost apelat de mai multe ori pentru același EditText, toate listener-ele vor procesa aceeași modificare. În formularele cu adăugare dinamică de View, acest lucru duce la duplicarea verificărilor și un comportament imprevizibil. Verifică întotdeauna dacă listenerul a fost deja adăugat anterior sau folosește o singură instanță.

Întrebări frecvente

Cu ce se deosebește onTextChanged de afterTextChanged?

OnTextChanged este apelat în momentul modificării textului, când caracterele noi nu au fost încă adăugate. Această metodă este potrivită pentru animație și logare. AfterTextChanged este apelat după aplicarea completă a modificărilor și oferă acces la textul final prin parametrul Editable. Pentru validare și citirea valorii folosește afterTextChanged.

Cum să eviți apelul recursiv al TextWatcher?

Folosește un flag de blocare de tip Boolean care este setat la true înainte de modificarea textului în interiorul afterTextChanged. La începutul metodei verifică flagul: dacă este true — ieși. Alternativ, poți compara valoarea veche cu cea nouă și modifica textul doar la o diferență reală.

Este necesar să se elimine TextWatcher la distrugerea Activity?

Da, obligatoriu. Clasa anonimă TextWatcher menține o referință la Activity prin closure. Dacă listenerul nu este eliminat, Activity nu poate fi colectat de garbage collector. Apelează întotdeauna removeTextChangedListener în onDestroyView pentru Fragment sau onDestroy pentru Activity.

Se poate folosi TextWatcher în RecyclerView?

Da, dar cu prudență. În RecyclerView, ViewHolder-urile sunt reutilizate, iar TextWatcher de pe poziția anterioară poate rămâne activ. Elimină întotdeauna vechiul TextWatcher înainte de a seta unul nou în metoda onBindViewHolder. Folosește taguri sau câmpuri separate în ViewHolder pentru a stoca referința la listener.

Care metodă este cea mai bună pentru căutarea cu autocompletare?

Pentru câmpul de căutare folosește afterTextChanged împreună cu debounce (întârziere). Implementează un timer de 300-500 ms care se resetează la fiecare nouă modificare a textului. Asta previne trimiterea cererii la server la fiecare apăsare de tastă și reduce încărcarea API-ului.

Rezumat

  • TextWatcher — interfață Android pentru monitorizarea modificărilor textului în EditText și TextView, care implementează trei metode de callback.
  • Metoda afterTextChanged — alegerea optimă pentru validarea și citirea textului final după modificări.
  • Apelul recursiv — principalul pericol al TextWatcher, prevenit printr-un flag de blocare.
  • Eliminarea listenerului este obligatorie pentru prevenirea scurgerii de memorie la distrugerea Activity sau Fragment.
  • Validarea în timp real cu TextWatcher îmbunătățește UX și permite afișarea instantanee a erorilor.
  • Debounce este necesar la implementarea căutării și autocompletării pentru reducerea încărcării serverului.
  • Alegerea corectă a metodei — cheia funcționării stabile: beforeTextChanged pentru salvarea stării, onTextChanged pentru loguri, afterTextChanged pentru verificarea finală.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și