我的Activity有SearchView,它应该有过滤查询。我通过onQueryTextListener过滤它。想法是禁用键入不允许的字符,如点,逗号,斜线等 - 只允许[A-Z] 这是代码(我使用的是Kotlin,但它对Java来说是可读的):
var shouldQueryChangeBeInvoked = true
override fun onCreate(savedInstanceState: Bundle?) {
...
searchField.setOnQueryTextListener(this)
}
override fun setSearchQuery(query: String) {
shouldQueryChangeBeInvoked = false
searchField.setQuery(query, false)
shouldQueryChangeBeInvoked = true
}
override fun onQueryTextChange(newText: String?): Boolean {
if (!shouldQueryChangeBeInvoked) {
return false
}
val validQuery = validateQuery(newText)
validQuery?.let { setSearchQuery(it) }
return false
}
当我键入时,例如“ABC”。它转换为“ABC”。所以,它工作正常。 但是当我输入dot(“。”)第二次onQueryTextChange根本没有调用时 - 我在方法的第一行设置了断点。 它在两部不同的手机上进行了测试,因此它不是键盘设置或类似的。 为什么监听器不会调用?
修改
验证我使用Regex进行的查询:
fun validateQuery(query: String?): String? {
val regex = Regex("^([A-Z]+)")
// Return first match or null
return query?.let { regex.find(it.toUpperCase()) }?.value
}
不关心正则表达式创建 - 我通过DI提供它,因此,它每次活动只创建一次。 也许这可能有问题?
答案 0 :(得分:0)
我发现问题:在onQueryTextChange中更改查询文本是不好的 - 如果我们查看SearchView类内部,就会有这样的代码:
void onTextChanged(CharSequence newText) {
...
if (mOnQueryChangeListener != null && !TextUtils.equals(newText, mOldQueryText)) {
mOnQueryChangeListener.onQueryTextChange(newText.toString());
}
mOldQueryText = newText.toString();
}
因此,旧的查询文本将更新两次 - 第一次使用正确的查询“ABC”,第二次使用错误的“ABC ..”,正如我所理解的那样。
我会在onQueryTextChange
之后单独询问有关更改查询的其他问题答案 1 :(得分:0)
非常感谢@pskink!
我已经使用过滤器输入查询实现了自定义SearchView,并且能够在setQuery上禁用触发onQueryTextChange。 这是Kotlin,让我们继续这种美丽的语言:) 我希望它对某人有用。