androidandroid-edittextandroid-textwatcher

Manipulate or capture EditText input efficiently


What i'm trying to achieve

I want to convert every char the user inputs to another char and display it in the EditText.

What i've done

My first approach is implemented using a TextWatcher.

     private val textWatcher2 = object : TextWatcher {
        private var byUser = true

        override fun afterTextChanged(s: Editable?) {


        }

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

        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            if (!byUser) return

            byUser = false

            val t = this@ManipulatingEditText.text.toString()
            val m = convert(t.last())
            val s = t.substring(0, t.length - 1) + m
            this@ManipulatingEditText.setText("")
            this@ManipulatingEditText.setText(s)
            this@ManipulatingEditText.setSelection(this@ManipulatingEditText.text!!.length)

            byUser = true
        }
    }

    /*This is just an mock of my real implementation. But the same delay occurs*/
    fun convert(c: Char) : String {
        return c.toString()
    }

This is working: Every new input char is converted via the convert(Char) function. Unfortunately this solution is incredibly slow and inefficient. There is a short delay after each input and you can't type fast.

This solution is not suitable for a production app. But i have not found another solution yet (Debouncing or deffering via RxJava doesn't work because some chars get skipped or race conditions apply) that works better.

Any ideas, solutions or help is appreciated.


Solution

  • I changed a few things and saw a big decrease in lagginess, though I can't say which had the most (if any) impact: