SearchView不会在第二个点上调用onQueryTextChange

时间:2017-07-13 09:33:00

标签: android regex listener searchview

我的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提供它,因此,它每次活动只创建一次。 也许这可能有问题?

2 个答案:

答案 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,让我们继续这种美丽的语言:) 我希望它对某人有用。

这是Code on Gist