When the user types into the SearchView
widget, the app should make an
API call (in background thread) to fetch search results from server, an
I use such an approach on a production app.
RxSearchView.queryTextChanges(searchView)
.debounce(300, TimeUnit.MILLISECONDS)
.filter(new Predicate<String>() {
@Override
public boolean test(String text) throws Exception {
if (text.isEmpty()) {
return false;
} else {
return true;
}
}
})
.distinctUntilChanged()
.switchMap(new Function<String, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(String query) throws Exception {
return dataFromNetwork(query);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String result) throws Exception {
textViewResult.setText(result);
}
});
Remember that you can actually use multiple observeOn
and multiple subscribeOn
operators in your rx chain.
Try this:
RxSearchView.queryTextChanges(searchView)
.debounce(400, TimeUnit.MILLISECONDS)
.map(CharSequence::toString)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.switchMap(query -> retrofitService.search(query))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Item>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.e(LOG_TAG, "Error", e);
}
@Override
public void onNext(List<Item> items) {
// adapter.addItems(...)
}
});
This will basically result in this Thread usage: