当与android搜索功能中使用的Rx Java一起使用时,如何停止多次改装调用?
我的Android应用程序中有搜索功能。searchView在SearchTextChanged(String oldQuery、String newQuery)上有回调当与android搜索功能中使用的Rx Java一起使用时,如何停止多次改装调用?,android,retrofit,rx-java,retrofit2,rx-android,Android,Retrofit,Rx Java,Retrofit2,Rx Android,我的Android应用程序中有搜索功能。searchView在SearchTextChanged(String oldQuery、String newQuery)上有回调onSearchTextChanged。每当用户在搜索字段中输入任何文本时,此回调函数都会调用。我在这个回调中有一个REST调用,它在每次键入每个单词时都会触发。这会导致多次调用REST。我想避免这种情况。我只希望一次只激活一个实例,这是最近的一个实例,并且只要键入新字母,所有其他调用都应立即取消。下面是代码详细信息 @Ove
onSearchTextChanged
。每当用户在搜索字段中输入任何文本时,此回调函数都会调用。我在这个回调中有一个REST调用,它在每次键入每个单词时都会触发。这会导致多次调用REST。我想避免这种情况。我只希望一次只激活一个实例,这是最近的一个实例,并且只要键入新字母,所有其他调用都应立即取消。下面是代码详细信息
@Override
public void onSearchTextChanged(String oldQuery, String newQuery) {
floatingSearchView.showProgress();
moviesAPI.searchQuery(newQuery)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Search>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted() called");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError() called with: e = [" + e + "]");
}
@Override
public void onNext(Search search) {
floatingSearchView.hideProgress();
floatingSearchView.swapSuggestions(search.getSearchResults());
Log.d(TAG, "onNext() called with: search = [" + search + "]");
}
}
);
}
@覆盖
已更改SearchTextChanged上的公共void(字符串oldQuery、字符串newQuery){
floatingSearchView.showProgress();
searchQuery(newQuery)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
d(标记“onCompleted()调用”);
}
@凌驾
公共无效申报人(可丢弃的e){
d(标记,“onError()调用时使用:e=[“+e+”]);
}
@凌驾
public void onNext(搜索){
floatingSearchView.hideProgress();
floatingSearchView.swapSuggestions(search.getSearchResults());
d(标记,“onNext()调用时使用:search=[“+search+]”);
}
}
);
}
您可能希望在键入时使用debounce延迟搜索请求(并且仅在用户停止键入x个持续时间后)
此外,为了在新请求到达时取消旧请求,您可以将文本更改事件转换为事件流(手动或使用RxBindings之类的库),然后将每个新文本事件映射到查询。
当新的请求由新的搜索文本流驱动到达时,switchMap操作员将取消仍在进行的上一个请求
您可以找到各种使用rxjava实现android搜索建议的示例,如Kaushik Gopal的示例:
代码示例,此示例使用库轻松地将textChanages事件获取为可观察流
RxTextView.textChangeEvents(tv)
.debounce(300, TimeUnit.MILLISECONDS)
.switchMap(new Func1<TextViewTextChangeEvent, Observable<SearchResult>>() {
@Override
public Observable<SearchResult> call(
TextViewTextChangeEvent textViewTextChangeEvent) {
return moviesAPI.searchQuery(textViewTextChangeEvent.text().toString())
.subscribeOn(Schedulers.io());
}
})
.subscribe(new Subscriber<SearchResult>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted() called");
}
@Override
public void onError(Throwable e) {
floatingSearchView.hideProgress();
Log.d(TAG, "onError() called with: e = [" + e + "]");
}
@Override
public void onNext(SearchResult search) {
floatingSearchView.hideProgress();
floatingSearchView.swapSuggestions(search.getSearchResults());
Log.d(TAG, "onNext() called with: search = [" + search + "]");
}
});
rxtview.textchangevents(电视)
.debounce(300,时间单位为毫秒)
.switchMap(新函数1(){
@凌驾
公共可观测呼叫(
text查看text更改事件text查看text更改事件){
返回moviesAPI.searchQuery(textViewTextChangeEvent.text().toString())
.subscribeOn(Schedulers.io());
}
})
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
d(标记“onCompleted()调用”);
}
@凌驾
公共无效申报人(可丢弃的e){
floatingSearchView.hideProgress();
d(标记,“onError()调用时使用:e=[“+e+”]);
}
@凌驾
public void onNext(搜索结果搜索){
floatingSearchView.hideProgress();
floatingSearchView.swapSuggestions(search.getSearchResults());
d(标记,“onNext()调用时使用:search=[“+search+]”);
}
});
如果您在输入每个字符后延迟几秒钟以实际启动请求,会怎么样?那么,当用户输入更多的字母时,您并不是发送每个字母。正如下面的回答中所述,您可能需要debounce运算符。看一看。运行应用程序并查找显示搜索的库。所以我喜欢,但没有成功。你能帮我写一些代码吗?你给我的链接没有任何示例代码。在你的示例中,你从查询obsevable开始,这里的事件源是文本更改事件流,然后你需要使用数值和时间单位(忽略所有事件,而它们之间没有延迟X),而不是函数,然后,您应该将文本更改事件的每个发射映射到服务器查询,最后订阅并处理结果,在回答中添加了示例代码我正在使用第三方库搜索视图如何将这些视图转换为可观察的?您可以查看RxBinding代码:或者更一般地了解如何使用RxJava包装异步调用:简短的回答是使用observable.fromEmitter创建可观察的(或者不再推荐使用创建方法),有注册和收听textview事件和发出onNext与每个event@Ajinkya如果有帮助,请接受我的回答