等到用户停止输入后再在搜索视图中执行大量搜索

Wait until the user stops typing before executing a heavy search in searchview

搜索是我应用程序的核心,我需要它才能正常运行。现在我有一个 SearchView。我需要内联显示结果,所以我使用了这段代码。

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            srl.setVisibility(View.GONE);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            currentQuery = query;
            if (query.length()>= 3) {
                searchFor(currentQuery);
            } else {
                srl.setVisibility(View.GONE);
            }
            return false;
        }
    });

问题可能很明显。因为我使用 firebase,所以我的 searchFor() 函数相当繁重,我不需要为每个字母都执行它。这不仅会破坏用户体验,如果您写下更长的单词,有时还会使我的应用崩溃。

我想要的是在用户停止输入时进行搜索。我想我需要有一个处理程序将它延迟一秒钟,然后在每次按下字母键并设置一个新键时取消该处理程序。这在理论上是有道理的。我只是无法通过 searchView 自行解决这个问题。

不胜感激!

最简单的方法是 RxJava's debounce 运算符。

结合 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`
            }
        });

这应该对您有所帮助,您的 class 需要实施 "SearchView.OnQueryTextListener" 并且 "cntr" 必须在您的 class

中声明

这已经为普通用户输入提供了 twinked,如果您想等待更多,只需提高 "waitingTime"。

请求应该在 "onFinish"

    private int waitingTime = 200;
    private CountDownTimer cntr;

    @Override
    public boolean onQueryTextChange(String newText) {
    if(cntr != null){
        cntr.cancel();
    }
    cntr = new CountDownTimer(waitingTime, 500) {

        public void onTick(long millisUntilFinished) {
            Log.d("TIME","seconds remaining: " + millisUntilFinished / 1000);
        }

        public void onFinish() {
            Log.d("FINISHED","DONE");
        }
    };
    cntr.start();
    return false;
}

参考:

对于那些不想使用 RxJava 的人:

final Handler handler = new Handler();
SearchView searchView = (SearchView) findViewById(R.id.search_view);

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

        public boolean onQueryTextChange(final String query) {
            handler.removeCallbacksAndMessages(null);
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    // do stuff
                }
            }, 400);
            return false;
        }
});