我需要在我的 Android 应用程序中实现搜索功能。该 API 不是合适的搜索 API,它是这样的
https://example.com/api/list/photos/?start=0&end=30&search=something
所以,基本上,我必须为搜索查询的每个字母查询后端,并且端点已分页,以便我可以控制要显示的条目数。
我读了some code它使用 RxJava 为搜索添加时间限制约束,因此我至少可以最大限度地减少对后端的调用次数。但我面临的问题是,如果我输入“s”,一个请求就会出现,如果我输入“so”,那么另一个请求就会出现(假设我输入有延迟),所以我可能会得到结果由于某种原因,在“s”之前使用“so”,然后整个搜索将被破坏。此外,如果已发出请求,响应将在某个时候出现,我将需要根据该响应更改 UI,即使那不是我想要搜索的最终查询。
我正在使用 Retrofit 1.9,每当我收到响应时,我都会根据结果更新 recyclerView。有没有办法根据上述情况取消Retrofit请求呢?让这个东西正常工作的最佳设计或实现是什么?任何帮助将不胜感激。
编辑 :这是我自己写的。如果可以任何方式改进,请告诉我。
Subscription subscription = RxTextView.textChangeEvents(inputSearch)
.debounce(400, TimeUnit.MILLISECONDS)// default Scheduler is Computation
.filter(new Func1<TextViewTextChangeEvent, Boolean>() {
@Override
public Boolean call(TextViewTextChangeEvent changes) {
return !TextUtils.isEmpty(inputSearch.getText().toString());
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSearchObserver());
private void getSearchResults(String s) {
LogUtil.i(TAG, "getSearchResults called");
indicator.setVisibility(View.VISIBLE);
DiscoverAPI discoverAPI = restAdapter.create(DiscoverAPI.class);
discoverAPI.getSearchResults(0, 10, s, new Callback<List<Result>>() {
@Override
public void success(List<Result> results, Response response) {
LogUtil.i(TAG, "discover api successful");
list.clear();
if (adapter != null) {
adapter.notifyDataSetInvalidated();
}
list.addAll(results);
if (adapter == null) {
adapter = new SearchGalleryAdapter(TestActivity.this, list);
listView.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
indicator.setVisibility(View.GONE);
}
@Override
public void failure(RetrofitError error) {
LogUtil.i(TAG, "discover api failed");
}
});
}
最佳答案
你可以尝试这样的事情:
RxTextView.afterTextChangeEvents(mTextView)
.map(new Func1<TextViewAfterTextChangeEvent, String>() {
@Override
public String call(TextViewAfterTextChangeEvent textViewAfterTextChangeEvent) {
return textViewAfterTextChangeEvent.editable().toString();
}
})
.switchMap(new Func1<String, Observable<SearchResponse>>() {
@Override
public Observable<SearchResponse> call(String query) {
return mApiService.search(query);
}
})
- afterTextChangeEvents 在您的 TextView 上创建文本更改事件流
- map 将 TextViewAfterTextChangeEvent 映射到已键入的String
- switchMap 的工作方式几乎与 flatMap 类似,因此它将您的事件映射到另一个事件流(在本例中为 Api 请求),但是,在发出另一个事件后,它取消订阅之前的流(因此之前的 Api 请求结果将被忽略)
关于android - 使用 Retrofit 搜索 api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36932747/