Android - 覆盖 onTextChanged 不会改变行为



我正在尝试创建一个自定义EditText,它将在执行onTextChanged之前实现延迟。

class CustomEditText(context: Context, attributeSet: AttributeSet) : AppCompatEditText(context, attributeSet) {
private var millisDelay: Long = 500
private var timer: Timer? = null
override fun onTextChanged(
text: CharSequence?,
start: Int,
lengthBefore: Int,
lengthAfter: Int
) {
doDelay {
Log.d("somekoder", "Calling onTextChanged after $millisDelay milliseconds")
super.onTextChanged(text, start, lengthBefore, lengthAfter)
}
}
fun setDelay(millisDelay: Long){
this.millisDelay = millisDelay
}
private fun doDelay(then: () -> Unit){
timer?.cancel()
timer = Timer()
// Log.d("somekoder", "Got action. Waiting $millisDelay milliseconds.")
timer?.schedule(timerTask {
then.invoke()
}, millisDelay)
}
}

这是我的主要活动

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
search.setDelay(1000)
search.addTextChangedListener {
Log.d("somekoder", "MainActivity: onTextChanged")
}
}
}

这就是我的日志:

D/somekoder: MainActivity: onTextChanged
D/somekoder: MainActivity: onTextChanged
D/somekoder: MainActivity: onTextChanged
D/somekoder: MainActivity: onTextChanged
D/somekoder: Calling onTextChanged after 1000 milliseconds

MainActivity onTextChanged被调用,即使我在那里有延迟。有人能解释一下我做错了什么吗?提前感谢!

使用addTextChangedListener((,您可以添加多个侦听器,而不像setOnclickListener那样一次只能设置一个侦听器。作为一个通用的api实现,您的视图有两个监听器。在您的情况下,两种实现方式不同。延迟不会影响其他侦听器的执行。

onTextChanged方法是一个受保护的方法,其工作方式类似于TextView子类的内部侦听器。默认实现是空的,当文本更改时以及在侦听器之后调用它。因此,它完全独立于听众。

如果你想延迟监听器(而不是文本更改(,你可以这样做。但我不推荐它,因为我认为它会引起问题,尤其是在afterTextChanged中(因为它会更改文本(。

override fun addTextChangedListener(watcher: TextWatcher) {
super.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
doDelay {
watcher.beforeTextChanged(s, start, count, after)
}
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
doDelay {
watcher.onTextChanged(s, start, before, count)
}
}
override fun afterTextChanged(s: Editable?) {
doDelay {
watcher.afterTextChanged(s)
}
}
})
}

最新更新