Rx SearchView needs to cancel on going request wit

2019-09-06 09:17发布

I am using

RxSearchView.queryTextChangeEvents

to detect the events of “Search As You Type” and also when you submit a search, SAYT is to get suggestions and when you do a submit, it executes a full search.

There are 2 problems I am having at the moment.

When you are typing, and getting suggestions, but suddenly you click submit then it executes the full search but the problem is that if there is an on going suggestion request there might be the case that they appear on screen when they should not as the full search has priority.

So I would like to cancel (unsubscribe) the request from the suggestions in case there is a submit on the full search.

How can I achieve this with this code?

Another problem is that when I am deleting the search term in the search view and it gets empty, then it clears the adapter but there are cases when I clear the search text, there is still an on going suggestions request and it sets the results but it just clear, so I would like to guarantee that if the user clears the searchview, it cancels all the requests.

Here is the Code I am using.

 RxSearchView.queryTextChangeEvents(searchView)
                .skip(1)
                .throttleLast(100, TimeUnit.MILLISECONDS)
                .debounce(200, TimeUnit.MILLISECONDS)
                .onBackpressureLatest()
                .observeOn(AndroidSchedulers.mainThread())
                .filter(new Func1<SearchViewQueryTextEvent, Boolean>() {
                    @Override
                    public Boolean call(SearchViewQueryTextEvent searchViewQueryTextEvent) {
                        final boolean empty = TextUtils.isEmpty(searchViewQueryTextEvent.queryText());
                        if (empty) {
                            //Dont show anything  clear adapter
                            clearAdapter();
                        }
                        return !empty;
                    }
                })
                .concatMap(new Func1<SearchViewQueryTextEvent, Observable<Object>>() {
                    @Override
                    public Observable<Object> call(SearchViewQueryTextEvent searchViewQueryTextEvent) {

                        String searchTerm = searchViewQueryTextEvent.queryText().toString();
                        boolean submitted = searchViewQueryTextEvent.isSubmitted();
                        //Hide RecyclerView
                        //Show loading indicator
                        showLoading();
                        Observable<Object> observable;
                        if (submitted) {
                            observable = getFullSearch(searchTerm);
                        } else {
                            observable = getSuggestionsSearch(searchTerm);
                        }
                        return observable
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .doOnCompleted(new Action0() {
                                    @Override
                                    public void call() {
                                        //Show RecyclerView
                                        //Hide loading indicator
                                        showContent();
                                    }
                                });
                    }
                })
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onNext(Object object) {
                        //Set data on recyclerview and notify change.
                        setData(object);
                    }

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                });
    }

1条回答
▲ chillily
2楼-- · 2019-09-06 09:42

You might want to try switchMap instead, it just uses the last emited value from the observable.

From the docs:

Returns a new Observable by applying a function that you supply to each item emitted by the source Observable that returns an Observable, and then emitting the items emitted by the most recently emitted of these Observables. The resulting Observable completes if both the upstream Observable and the last inner Observable, if any, complete. If the upstream Observable signals an onError, the inner Observable is unsubscribed and the error delivered in-sequence.

enter image description here

查看更多
登录 后发表回答