Search code examples
androidkotlinandroid-edittext

"onTextChanged()" returning old EditText text value


I have a method that is supposed to return the current updated value of an EditText text. But, for some reason, for it to actually work at first, the input has to change 2 times. And, when it does, it returns the previous value, not the current one.

fun EditText.text(): String {
    var whatever = text.toString()
    doOnTextChanged { text, _, _, _ -> whatever = text.toString() }

    return whatever
}

Don't know if I made myself clear, but I've been trying to solve this for a while, without any success.


Solution

  • Your whatever variable does not outlive the function you've created. Here's what happens when you call your edit() function:

    1. A variable whatever is created and assigned the current value of the text in the text view.
    2. A new TextWatcher is created and added to the TextView. This TextWatcher updates the value of whatever when the text is changed, which is a pointless action, because whatever cannot be accessed by the time the TextWatcher is active.
    3. The value of whatever is returned. It will be the same value that it was in step 1, because nothing has had a chance to change it yet.

    When you call your function multiple times, you are adding multiple useless TextWatchers to your TextView. Your function might as well be

    fun EditText.text() = text.toString()
    

    which is not very useful, but effectively does the same thing as your original function minus adding unnecessary TextWatchers.

    Without context of what you're trying to do exactly, I can't recommend how to fix your project. Your function already returns the latest changed value of the EditText, but you describe it as though the value is lagging. I'd have to see the code where you're calling this function to get an idea of what you're trying to do.

    I can take a guess that maybe you didn't realize that Strings are immutable. The String returned by your function doesn't get updated just because the variable that was originally pointing to it gets pointed to something else.

    If you want something to happen when the text changes, put the action directly in your lambda. There's not much point in a TextWatcher that simply updates a variable since the latest value of the text can always be retrieved directly from the TextView anyway.