I want to convert every char the user inputs to another char and display it in the EditText
.
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.
I changed a few things and saw a big decrease in lagginess, though I can't say which had the most (if any) impact:
setText
with manipulating the Editable
directlyonTextChanged
callback to the afterTextChanged
callback, since that's the callback that gives us an Editable
and not a CharSequence
simplified the logic around deciding what the new text is going to be--hopefully this is still doing what you intended; it's a bit unclear to me from the sample code you provided
private val textWatcher2 = object : TextWatcher {
private var byUser = true
override fun afterTextChanged(s: Editable?) {
if (!byUser) return
byUser = false
s?.let {
if (s.isNotEmpty()) {
s.replace(s.length - 1, s.length, convert(s.last()))
}
}
byUser = true
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}