搜索是我应用的核心,我需要它才能正常运行。现在我有一个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来解决这个问题。
帮助将不胜感激!
答案 0 :(得分:3)
实现这一目标的最简单方法是RxJava's debounce运营商。
结合杰克沃顿的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`
}
});
答案 1 :(得分:1)
这应该对您有帮助,您的类需要实现“ SearchView.OnQueryTextListener”,并且必须在您的类中声明“ cntr”
对于普通用户来说,这已经很麻烦了,如果您想等待更多,只需增加“ 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;
}
参考:Delay call to onQueryTextChange() in SearchView.OnQueryTextListener with SearchView
答案 2 :(得分:0)
对于那些不想使用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;
}
});