Counting Chars in EditText Changed Listener
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Android's TextWatcher interface provides three callback methods that fire as text changes in an EditText. To count characters, use the afterTextChanged callback — it fires after the modification is complete, giving you the final text to measure. Pair it with a TextView to show a live character count, and optionally enforce a maximum length by trimming excess input inside the callback.
TextWatcher Basics
Use afterTextChanged for character counting because the Editable reflects the final state of the text.
Basic Character Counter (Java)
Kotlin Version
Using Kotlin Extension (doAfterTextChanged)
doAfterTextChanged is a Kotlin extension that eliminates the need to implement all three TextWatcher methods.
Enforcing Maximum Length
Using InputFilter (Preferred)
This prevents the user from typing beyond 280 characters. Combine with TextWatcher for the count display.
Using TextWatcher (Programmatic Trim)
Modifying s inside afterTextChanged triggers the TextWatcher again. The re-entry is safe because the trimmed text will pass the length check on the second call.
XML Layout
android:maxLength="280" in XML is equivalent to InputFilter.LengthFilter(280) in code.
Counting Words Instead of Characters
Jetpack Compose Version
In Compose, there is no TextWatcher — the onValueChange lambda handles all text changes.
Common Pitfalls
- Counting in
onTextChangedinstead ofafterTextChanged:onTextChangedfires during the edit, so theCharSequencemay not reflect the final state if multiple watchers modify the text. UseafterTextChangedfor accurate counts. - Infinite loop when modifying Editable: Calling
s.replace()ors.delete()insideafterTextChangedre-triggers the watcher. Always guard modifications with a length check to prevent infinite recursion. - Forgetting to remove TextWatcher: If you add a watcher in
onResume, remove it inonPausewithremoveTextChangedListener(). Otherwise, duplicate watchers accumulate on configuration changes. - Unicode multi-byte characters:
s.length()counts UTF-16 code units, not user-visible characters. An emoji like a flag uses 4 code units but appears as 1 character. UseCharacter.codePointCount()for accurate visible character counts. - Using
android:maxLengthand programmatic trim together: If both are set, theInputFilterprevents the text from exceeding the limit, so theafterTextChangedtrim never triggers. Use one or the other, not both.
Summary
- Use
afterTextChangedinTextWatcherto count characters after the edit is finalized - Display remaining characters with a
TextViewupdated inside the callback - Use
InputFilter.LengthFilterorandroid:maxLengthto enforce limits at the input level - Kotlin's
doAfterTextChangedextension simplifies the implementation - In Jetpack Compose, handle counting in the
onValueChangelambda - Guard any text modifications inside
afterTextChangedto avoid infinite re-triggering
Related reading
- Create a rounded button / button with border-radius in Flutter
- Create a rounded button / button with border-radius in Flutter
- Create aar file in Android Studio
- Create space at the beginning of a UITextField
- Create space at the beginning of a UITextField
- Create tap-able links in the NSAttributedString of a UILabel?
- Create thread safe array in Swift
- Create thread safe array in Swift
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.