Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent onTextChanged() behaviour

I wrote the code below to figure out how onTextChanged() method works:

override fun onTextChanged(string: CharSequence?, start: Int, before: Int, count: Int) {
                Log.d(TAG, "onTextChanged triggered.")
                Log.d(TAG, "string = $string")
                Log.d(TAG, "start = $start")
                Log.d(TAG, "before = $before")
                Log.d(TAG, "count = $count")
                Log.d(TAG, "____________________________________________________________")

Here's what I noticed: when I'm typing letters only, the count is pretty straightforward:

onTextChanged triggered.
string = a
start = 0
before = 0
count = 1
____________________________________________________________
onTextChanged triggered.
string = aa
start = 0
before = 1
count = 2
____________________________________________________________
onTextChanged triggered.
string = aaa
start = 0
before = 2
count = 3
____________________________________________________________
onTextChanged triggered.
string = aaaa
start = 0
before = 3
count = 4
____________________________________________________________
onTextChanged triggered.
string = aaaaa
start = 0
before = 4
count = 5
____________________________________________________________

Now if I add 3 (or more) digits and then keep on typing letters, this is what happens:

onTextChanged triggered.
string = aaaaa2
start = 0
before = 5
count = 6
____________________________________________________________
onTextChanged triggered.
string = aaaaa22
start = 0
before = 6
count = 7
____________________________________________________________
onTextChanged triggered.
string = aaaaa222
start = 0
before = 7     
count = 8
____________________________________________________________
onTextChanged triggered.
string = aaaaa222
start = 0
before = **8**      <---- This is when it gets funny
count = **8**
____________________________________________________________
onTextChanged triggered.
string = aaaaa222a
start = 8
before = 0
count = 1
____________________________________________________________
onTextChanged triggered.
string = aaaaa222aa
start = 9
before = 0
count = 1
 ____________________________________________________________
onTextChanged triggered.
string = aaaaa222aaa
start = 10
before = 0
count = 1
____________________________________________________________
onTextChanged triggered.
string = aaaaa222aaaa
start = 11
before = 0
count = 1
____________________________________________________________
onTextChanged triggered.
string = aaaaa222aaaaa
start = 12
before = 0
count = 1
____________________________________________________________

To me it seems like inputing 3 digits somehow changes the TextWatcher's behaivior making it treat everything that comes after as a Char rather than a CharSequence.

Is there an explanation to this behaviour?

like image 737
Vsevolod IV Avatar asked Jan 20 '26 13:01

Vsevolod IV


1 Answers

While I don't have an explanation why it happens with 3 digits, I found out that there is no guarantee when offesets will be invalidated at all. Check this this

"You are not told where the change took place because other afterTextChanged() methods may already have made other changes and invalidated the offsets. But if you need to know here, you can use Spannable#setSpan in onTextChanged(CharSequence, int, int, int) to mark your place and then look up from here where the span ended up."

One possible implemetation of TextWatcher would be this one. That way you will have the proper begin and end indexes.

like image 121
Ahmed Ahmedov Avatar answered Jan 22 '26 02:01

Ahmed Ahmedov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!