2017-02-05 22 views
1

У меня есть функция поиска в приложении для Android. SearchView имеет обратный вызов onSearchTextChanged(String oldQuery, String newQuery). Эта функция обратного вызова вызывает каждый раз, когда пользователь вводит любой текст в поле поиска. У меня есть вызов REST в этом обратном вызове, который запускается каждый раз, когда набирается каждое слово. Это приводит к нескольким вызовам REST. Я хочу этого избежать. Я просто хочу, чтобы только один экземпляр активен в то время, которое является последним, и все остальные вызовы должны быть немедленно отменены всякий раз, когда набирается новое письмо. Ниже приведены данные кода.Как остановить множественные переназначения при использовании с помощью Rx-Java, используемого в функции поиска для Android?

@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 + "]"); 
           } 
          } 

       ); 

    } 
+0

Что делать, если вместо этого вы добавили несколько секунд после каждого символа, введенного для фактического начала запроса? Затем вы не отправляете для каждой буквы, когда пользователь вводит больше. –

+0

Как указано в приведенном ниже ответе, вам, вероятно, нужен оператор debounce. Посмотрите @ https://github.com/ragdroid/rxify. Запустите приложение и найдите библиотеку, которая показывает поиск. – Raghunandan

ответ

1

Возможно, вы захотите использовать debounce для задержки поисковых запросов при вводе (и только после того, как пользователь перестанет печатать на протяжении продолжительности x).

Кроме того, для отмены старых запросов при поступлении нового запроса вы можете преобразовать события изменения текста в поток событий (вручную или с помощью библиотеки, такой как RxBindings), а затем переключить каждое новое текстовое событие на запрос. Оператор switchMap отменит предыдущий запрос, который все еще продолжается, когда новый запрос поступает с помощью нового текстового потока поиска.

вы нашли различные примеры реализации предложений поиска для андроида с rxjava, как этот по Кошику Гопал: instantauto-searching-text-listeners-using-subjects--debounce

пример кода, в данном примере используется RxBinding библиотеки легко получать 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 + "]"); 
        } 
       }); 
+0

Так что мне понравилось [это] (https://gist.github.com/asbadve/b3445231a5a46bfb5bb2e3ed8b29ef29.js), но не удастся. Можете ли вы мне помочь с некоторым кодом. Ссылка, которую вы мне дали, не имеет никакого образца кода. – Ajinkya

+0

в вашем примере, который вы начали с запроса obsevable, источником событий является текстовый поток изменений событий, тогда вам нужно отбросить его с помощью номера и единицы времени (игнорировать все события, пока между ними нет задержки X), и не функция, тогда вы должны переключаться каждую эмиссию события изменения текста на серверный запрос и, наконец, подписываться и обрабатывать результат, добавленный пример кода в ответ – yosriz

+0

Я использую стороннюю библиотеку для поиска, как я могу преобразовать эти представления в наблюдаемый? – Ajinkya