在SearchView中调节onQueryTextChange

ahe*_*ick 9 java search android searchview android-search

"限制"的最佳方法是什么,onQueryTextChange以便我的performSearch()方法每秒只调用一次而不是每次用户输入?

public boolean onQueryTextChange(final String newText) {
    if (newText.length() > 3) {
        // throttle to call performSearch once every second
        performSearch(nextText);
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

Ami*_*mit 21

基于aherrick的代码,我有一个更好的解决方案.而不是使用布尔'canRun',声明一个runnable变量,并在每次更改查询文本时清除处理程序上的回调队列.这是我最终使用的代码:

@Override
public boolean onQueryTextChange(final String newText) {
    searchText = newText;

    // Remove all previous callbacks.
    handler.removeCallbacks(runnable);

    runnable = new Runnable() {
        @Override
        public void run() {
            // Your code here.
        }
    };
    handler.postDelayed(runnable, 500);

    return false;
}
Run Code Online (Sandbox Code Playgroud)


azi*_*ian 8

我想出了一个使用RxJava的解决方案,特别是它的反跳操作符。

使用Jake Wharton方便的RxBinding,我们将获得以下内容:

RxSearchView.queryTextChanges(searchView)
        .debounce(1, TimeUnit.SECONDS) // stream will go down after 1 second inactivity of user
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Consumer<CharSequence>() {
            @Override
            public void accept(@NonNull CharSequence charSequence) throws Exception {
                // perform necessary operation with `charSequence`
            }
        });
Run Code Online (Sandbox Code Playgroud)


jc1*_*c12 8

如果您使用Kotlin和协程,则可以执行以下操作:

var queryTextChangedJob: Job? = null

...

fun onQueryTextChange(query: String): Boolean {

    queryTextChangedJob?.cancel()

    queryTextChangedJob = launch(Dispatchers.Main) {
        delay(500)
        performSearch(query)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 协程是前进的方向!感谢你的回答。 (3认同)

ahe*_*ick -1

我最终得到了类似于下面的解决方案。这样它应该每半秒触发一次。

        public boolean onQueryTextChange(final String newText) {

            if (newText.length() > 3) {

                if (canRun) {
                    canRun = false;
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {

                            canRun = true;
                            handleLocationSearch(newText);
                        }
                    }, 500);
                }
            }

            return false;
        }
Run Code Online (Sandbox Code Playgroud)