How to change TextView text on DataChange without calling back a TextWatcher listener

Viewed 13972

Consider:

TextView textView = new TextView(context);
    textView.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                                      int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {

            s.append("A");
        }
    });

If we add a TextWatcher to a TextView, and I want to append a letter to this TextView, every time the user writes a letter in it, but this keeps calling the TextWatcher Listener, so on to StackOverFlow error, so how can I append text without calling the TextWatcher Listener again?

5 Answers

Some pseudocode so you can do this:

Just change the focus...

So like this:

tv.isFocusable = false

tv.setText("my new text")

tv.isFocusable = true // Maybe post this to the message queue, so other jobs finish fist.


// Later on in your listener:

if(tv.isFocusable && tv.hasFocus())
    // Do something
else ignore

Kotlin Version

editText.addTextChangedListener(object: TextWatcher {
    override fun afterTextChanged(s: Editable?) {
        if (s.toString().isNotBlank()) {

            val formattedValue: String = // Do some formatting

            editText.removeTextChangedListener(this)
            editText.setText(formattedValue)
            editText.setSelection(editText.text.toString().length)
            editText.addTextChangedListener(this)
        }
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

    }

})
Related