0

I am using RxSearchView to query the text changes in a form of "Search as you type"

RxSearchView.queryTextChanges(searchView)

but I would like to also catch when the user submits the search, so then I have to use

RxSearchView.queryTextChangeEvents(searchView) or searchView.setOnQueryTextListener

When I use any of these last 2, it looks like they are cancelling the first RxSearchView.queryTextChanges, looks like that there can only be 1 observable attached to SearchView.

How can I observe both events at the same time?

Here is the full code

private void setupSearch() {
        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
                        }
                        return !empty;
                    }
                }).subscribe(new Subscriber<SearchViewQueryTextEvent>() {

            @Override
            public void onNext(SearchViewQueryTextEvent searchViewQueryTextEvent) {
                String searchTerm = searchViewQueryTextEvent.queryText().toString();
                if (searchViewQueryTextEvent.isSubmitted()) {
                    submitFullSearch(searchTerm);
                } else {
                    submitRecommendationsSearch(searchTerm);
                }
            }

            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
            }


        });
    }
Kenenisa Bekele
  • 835
  • 13
  • 34

1 Answers1

1

There is only one observable since it overwrites the view's listener, but you can use RxSearchView.queryTextChangeEvents(searchView) to monitor both types of events. It gives a stream of SearchViewQueryTextEvent events. For each event, you can check isSubmitted() to determine if it is a submission or a change event and fetch the current text with queryText().

Here is how could use ConnectableObservable to get the events into two streams to filter separately --

private void setupSearch() {
    ConnectableObservable<SearchViewQueryTextEvent>  searchObs = RxSearchView.queryTextChangeEvents(searchView).publish();
    searchObs.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
                    }
                    return !empty;
                }
            }).subscribe(new Subscriber<SearchViewQueryTextEvent>() {

        @Override
        public void onNext(SearchViewQueryTextEvent searchViewQueryTextEvent) {
            String searchTerm = searchViewQueryTextEvent.queryText().toString();
            if (!searchViewQueryTextEvent.isSubmitted()) {
                submitRecommendationsSearch(searchTerm);
            }
        }

        @Override
        public void onCompleted() {
        }

        @Override
        public void onError(Throwable e) {
        }
    });

    searchObs.subscribe(new Subscriber<SearchViewQueryTextEvent>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(SearchViewQueryTextEvent searchViewQueryTextEvent) {
            if (searchViewQueryTextEvent.isSubmitted()) {
                submitFullSearch(searchTerm);
            }
        }
    });

    Subscription searchSub = searchObs.connect();
iagreen
  • 31,470
  • 8
  • 76
  • 90
  • I just updated the answer with the full code but the thing is that the debounce and throttleLast will also affect the search with the submit and I was hoping to separate them – Kenenisa Bekele Dec 02 '16 at 14:45
  • there is also this example https://github.com/kmdupr33/iosched/blob/feature/rxjava_rewrite/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java but I can't find the DelegatingOnQueryTextListener.java class to test it – Kenenisa Bekele Dec 02 '16 at 14:50
  • @JavierVargas If you need multiple subscriptions, take a look at `ConnectableObservable`s (https://github.com/ReactiveX/RxJava/wiki/Connectable-Observable-Operators). You can then filter each stream separately. – iagreen Dec 02 '16 at 16:04
  • Thanks for your answer, I have posted another question that is related to this if you have a chance to take a look. http://stackoverflow.com/questions/40962300/rx-searchview-needs-to-cancel-on-going-request-with-less-priority – Kenenisa Bekele Dec 04 '16 at 18:52