TextWatcher: co to je, rozhraní TextWatcher a implementace v Androidu

Autor: IT Sectr Publikováno: 2026-07-08 Doba čtení: 6 min

TextWatcher je rozhraní Androidu, které umožňuje sledovat změny textu v EditText a dalších TextView v reálném čase. Vývojář dostává oznámení ve třech fázích: před změnou, během změny a po změně textového obsahu. Podle Android Developers, 2026 se TextWatcher používá ve většině aplikací pro validaci vstupu, počítání znaků, implementaci vyhledávání s automatickým doplňováním a dynamické formátování textu. Rozhraní je nepostradatelné ve formulářích, kde je vyžadována okamžitá reakce na každé stisknutí klávesy.

Hlavní body

  • TextWatcher — vestavěné rozhraní Android SDK pro naslouchání změn textu v TextView a EditText.
  • Rozhraní obsahuje tři metody: beforeTextChanged, onTextChanged a afterTextChanged, každá odpovídá za svou fázi změny.
  • Metoda afterTextChanged je nejvhodnější pro validaci pole po dokončení vstupu uživatelem.
  • Rekurzivní volání — častá chyba: změna textu uvnitř TextWatcher vede k nekonečné smyčce.
  • TextWatcher se používá ve vyhledávacích polích, validaci formulářů, počítání znaků a automatickém formátování telefonního čísla.

Co je TextWatcher a k čemu slouží?

TextWatcher je rozhraní z balíčku android.text, které informuje aplikaci o změnách textu v objektech Editable. Při každém vložení, odstranění nebo nahrazení znaku TextWatcher sekvenčně volá tři metody a předává informace o pozici změn. To umožňuje vývojáři reagovat na akce uživatele okamžitě — bez dalších tlačítek nebo spouštěčů.

Hlavní scénáře použití zahrnují validaci polí v reálném čase: kontrola emailu při zadávání každého znaku, počítání zbývajících znaků v poli s omezením délky, implementace vyhledávání s odloženým odesíláním požadavku přes debounce. TextWatcher se také používá pro formátování vstupu — například automatické vkládání mezer v telefonním čísle nebo přidání masky pro datum.

Podle Android Developers je TextWatcher přítomen v 70 % aplikací pracujících s formuláři. Knihovny jako Material Design Components a TextInputEditText používají TextWatcher interně pro správu stavu chyby a zobrazení počítačů. Porozumění fungování tohoto rozhraní je nezbytné pro každého vývojáře Androidu.

Jak funguje rozhraní TextWatcher

TextWatcher se připojuje k libovolnému objektu TextView nebo EditText prostřednictvím metody addTextChangedListener. Když uživatel zadá nebo odstraní znak, Android nejprve zavolá beforeTextChanged, poté onTextChanged a nakonec afterTextChanged. V parametrech každé metody jsou předána data o měněném rozsahu: počáteční pozice, počet odstraněných znaků a počet přidaných znaků.

Je důležité pochopit, že po volání afterTextChanged objekt Editable již obsahuje aktuální hodnotu. Proto je v afterTextChanged vhodné kontrolovat konečný text pole. Do té chvíle data ještě nejsou plně aktualizována. Vývojáři si často pletou účel metod a používají onTextChanged pro konečnou validaci, i když správnou volbou je afterTextChanged.

Zvláštnosti volání metod

Při každém vložení, nahrazení nebo odstranění znaku je řetězec volání zaručeně proveden celý. Pokud se však uvnitř afterTextChanged změní text (prostřednictvím clear, append, insert), TextWatcher se spustí rekurzivně. To je nejčastější příčina StackOverflowError v Android formulářích. K prevenci rekurze se používá blokovací příznak.

Tři metody TextWatcher: beforeTextChanged, onTextChanged, afterTextChanged

Každá ze tří metod hraje svou roli v životním cyklu změny textu. Metoda beforeTextChanged(CharSequence s, int start, int count, int after) se volá před aplikací změn. Předává aktuální stav řetězce, počáteční pozici změny, počet odstraňovaných znaků a počet přidávaných znaků. Zde lze uložit předchozí hodnotu nebo zkontrolovat podmínky před úpravou.

Metoda onTextChanged se volá během změny, když již byly znaky odstraněny, ale nové ještě nebyly vloženy. Parametry: text po odstranění, počáteční pozice, počet odstraněných znaků a počet přidávaných znaků. Tato metoda je vhodná pro animaci nebo logování, ale ne pro práci s aktuálním konečným textem — ten ještě není sestaven.

Metoda afterTextChanged je nejžádanější. Přijímá objekt Editable a volá se po úplném aplikování změn. V této metodě lze číst konečnou hodnotu pole, provádět validaci, aktualizovat UI a měnit text (opatrně kvůli rekurzi).

Příklad implementace TextWatcher pro počítání znaků

Praktický příklad — počítadlo znaků pro vstupní pole, které se aktualizuje při každé změně textu. Takový prvek se často vyskytuje v kontaktních formulářích, příspěvcích a zprávách s omezením délky. Implementace pomocí TextWatcher vyžaduje několik řádků a nevyžaduje knihovny třetích stran.

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

V příkladu metoda afterTextChanged získává aktuální obsah pole prostřednictvím parametru s typu Editable. Délka textu se aktualizuje v samostatném TextView. Aby se předešlo rekurzi v tomto případě, mění se pouze counterText, nikoli samotný EditText, takže nevzniká smyčka. Při limitu 200 znaků lze po překročení blokovat další vstup.

Metody beforeTextChanged a onTextChanged zůstávají prázdné, protože pro počítání délky stačí konečný stav. Pokud je potřeba logovat každou změnu, kód lze přidat do onTextChanged. Taková flexibilita činí TextWatcher univerzálním nástrojem pro jakýkoli scénář práce s textovým vstupem.

TextWatcher pro validaci polí v reálném čase

Validace v reálném čase výrazně zlepšuje UX: uživatel vidí chybu okamžitě po zadání nesprávné hodnoty, nikoli až po stisknutí tlačítka odeslání. TextWatcher umožňuje okamžitou kontrolu emailu, hesla, telefonního čísla a dalších polí. Výsledek se zobrazí pomocí setError v EditText nebo prostřednictvím samostatného TextView s chybovou zprávou.

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

V příkladu je použit vestavěný Patterns.EMAIL_ADDRESS z Android SDK pro kontrolu emailu. Pokud text není prázdný a neodpovídá vzoru, poli je nastavena chyba prostřednictvím vlastnosti error. Při správném zadání se chyba vymaže. Je důležité nespouštět validaci na prázdném poli — uživatel možná ještě nezačal zadávat a chybová zpráva by byla předčasná.

Pro hesla a telefonní čísla se používají vlastní regulární výrazy nebo specializované knihovny. Například pro kontrolu složitosti hesla lze spočítat počet číslic, velkých a malých písmen. TextWatcher umožňuje aktualizaci indikátoru složitosti hesla v reálném čase, což pozitivně ovlivňuje konverzi registrace.

Typické chyby při práci s TextWatcher

První a nejkritičtější chyba — rekurzivní volání. Pokud se uvnitř afterTextChanged změní text stejného EditText (pomocí s.clear(), s.append() nebo s.insert()), TextWatcher se spustí znovu. To vytváří nekonečnou smyčku, která končí StackOverflowError. Řešením je použití blokovacího příznaku isUpdating nebo kontrola, zda se text skutečně změnil.

Druhý častý problém — únik paměti. TextWatcher obsahuje implicitní odkaz na Activity nebo Fragment prostřednictvím anonymní třídy. Pokud není listener odstraněn při zničení View, garbage collector nemůže uvolnit paměť. Řešením je použití komponent životního cyklu nebo explicitní volání removeTextChangedListener v onDestroyView.

Třetí chyba — použití nesprávné metody. Někteří vývojáři provádějí konečnou validaci v onTextChanged, aniž by čekali na afterTextChanged. V onTextChanged text ještě není plně aktualizován a čtení konečné hodnoty může vrátit nesprávná data. Správný přístup — umístit veškerou logiku čtení a kontroly konečného textu do afterTextChanged.

MetodaOkamžik voláníÚčelLze číst konečný text?
beforeTextChangedPřed změnouUložení předchozího stavuAno
onTextChangedBěhem změnyLogování, animaceNe
afterTextChangedPo změněValidace, počítání, aktualizace UIAno

Čtvrtá chyba — vícenásobné přidání TextWatcher. Pokud byl addTextChangedListener volán několikrát pro stejný EditText, všechny listenery budou zpracovávat stejnou změnu. Ve formulářích s dynamickým přidáváním View to vede k duplikování kontrol a nepředvídatelnému chování. Vždy kontrolujte, zda již byl listener dříve přidán, nebo použijte jedinou instanci.

Často kladené otázky

Čím se liší onTextChanged od afterTextChanged?

OnTextChanged je volán v okamžiku změny textu, když nové znaky ještě nebyly přidány. Tato metoda je vhodná pro animaci a logování. AfterTextChanged je volán po úplném aplikování změn a poskytuje přístup ke konečnému textu prostřednictvím parametru Editable. Pro validaci a čtení hodnoty používejte afterTextChanged.

Jak se vyhnout rekurzivnímu volání TextWatcher?

Použijte blokovací příznak typu Boolean, který se nastaví na true před změnou textu uvnitř afterTextChanged. Na začátku metody zkontrolujte příznak: pokud je true — ukončete metodu. Alternativně můžete porovnat starou a novou hodnotu a měnit text pouze při skutečném rozdílu.

Je třeba odstranit TextWatcher při zničení Activity?

Ano, nezbytně. Anonymní třída TextWatcher uchovává odkaz na Activity prostřednictvím closure. Pokud není listener odstraněn, Activity nemůže být garbage collectorem uvolněna. Vždy volejte removeTextChangedListener v onDestroyView pro Fragment nebo onDestroy pro Activity.

Lze použít TextWatcher v RecyclerView?

Ano, ale opatrně. V RecyclerView jsou ViewHoldery znovu používány a TextWatcher z předchozí pozice může zůstat aktivní. Vždy odstraňte starý TextWatcher před nastavením nového v metodě onBindViewHolder. Používejte tagy nebo samostatná pole ViewHolder pro uložení reference na listener.

Která metoda je nejlepší pro vyhledávání s automatickým doplňováním?

Pro vyhledávací pole používejte afterTextChanged v kombinaci s debounce (zpožděním). Implementujte časovač na 300-500 ms, který se resetuje při každé nové změně textu. To zabraňuje odesílání požadavku na server při každém stisknutí klávesy a snižuje zatížení API.

Shrnutí

  • TextWatcher — rozhraní Androidu pro sledování změn textu v EditText a TextView, implementující tři zpětné volací metody.
  • Metoda afterTextChanged — optimální volba pro validaci a čtení konečného textu po změnách.
  • Rekurzivní volání — hlavní nebezpečí TextWatcher, zabraňuje se blokovacím příznakem.
  • Odstranění listeneru je povinné pro zabránění úniku paměti při zničení Activity nebo Fragment.
  • Validace v reálném čase s TextWatcher zlepšuje UX a umožňuje okamžité zobrazení chyb.
  • Debounce je nezbytný při implementaci vyhledávání a automatického doplňování ke snížení zatížení serveru.
  • Správná volba metody — klíč ke stabilní práci: beforeTextChanged pro ukládání stavu, onTextChanged pro logy, afterTextChanged pro konečnou kontrolu.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také