我使用的是EditText
,我想要预设文本或让用户键入一些东西。我想把它改成"all-caps">所以我为TextWatcher
实现了大写函数。
您可以使用此EditText
和TextWatcher
多次进入和离开屏幕来回切换屏幕-这意味着我必须在屏幕进入/离开事件时从EditText
正确注册和取消注册TextWatcher
。
我注意到的是,如果我连续多次进入和离开屏幕,在第5次进入时,我的整个应用程序被冻结-所以有些东西阻塞了UI线程。
经过更深入的调查,我发现如果我调用editText.setText("some string")
,它将多次触发我的afterTextChanged
侦听器。在第5次输入时,它像一样在一行中触发了50次导致UI线程阻塞。
这是如何修复或它是Android方面的bug ?
代码:输入时初始化屏幕:
initEditTextListener()
App.log("FormScreen - setData")
formFirstEt?.setText(item.name)
private var inputWatcher: TextWatcher? = null
private fun initEditTextListener(){
formFirstEt?.onEditorAction{
formInputValidation(this.text.toString(), formFirstEt, App.getString("form_empty"), App.getString("form_empty_reason"))
validateData()
formSecondEt?.let { s -> if (s.isEnabled) s.requestFocus() }
}
inputWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
App.log("FormScreen - initEditTextListener - afterTextChanged")
validateData()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
App.log("FormScreen - initEditTextListener - onTextChanged")
validateData()
formFirstEt?.let { et -> onFormFirstInputChanged(s.toString(), this, et)}
}
}
inputWatcher?.let {formFirstEt?.addTextChangedListener(it)}
}
全大写转换函数(不应该触发texttwatcher)
fun onFormFirstInputChanged(s: String, tv: TextWatcher, et: EditText) {
et.removeTextChangedListener(tv)
if (isFirstInputValid(s)) {
with(et) {
text.clear()
append(s.toUpperCase(Locale.getDefault()))
setSelection(s.length)
}
} else {
val substring = s.substring(0, s.length - 1)
with(et) {
text.clear()
append(substring.toUpperCase(Locale.getDefault()))
setSelection(substring.length)
}
}
et.addTextChangedListener(tv)
}
离开前清理屏幕:
formFirstEt?.setText("")
inputWatcher?.let { formFirstEt?.removeTextChangedListener(it) }
inputWatcher = null
日志:
-- First time screen enter ---
2021-01-14 11:24:50.324 1136-1136/? I/Project: FormScreen - setData
2021-01-14 11:24:50.458 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:50.460 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
2021-01-14 11:24:52.838 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:52.841 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
-- Second time screen enter --
2021-01-14 11:24:56.324 1136-1136/? I/Project: FormScreen - setData
2021-01-14 11:24:56.366 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:56.367 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:56.368 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
2021-01-14 11:24:56.368 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:56.369 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
2021-01-14 11:24:56.369 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:56.370 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:56.370 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
2021-01-14 11:24:56.371 1136-1136/? I/Project: FormScreen - initEditTextListener - onTextChanged
2021-01-14 11:24:56.372 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
2021-01-14 11:24:56.372 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
2021-01-14 11:24:56.373 1136-1136/? I/Project: FormScreen - initEditTextListener - afterTextChanged
更新:这是Kotlin的一些行为。问题是formFirstEt?.setText("")
,我希望它会添加空字符串到EditText
,但显然它是添加字符终止符。Kotlin不能识别它的String
,而是默认的char array
,末尾有