2016-11-13 6 views
2

Я новичок в Rx мире и попытаться реализовать мой AutoCompleteTextView с RxJava, RxBinding и Retrofit 2.AutoCompleteTextView с Модернизированный 2 RxJava и RxBinding

Вот что я придумал что хлопотно: (. Может быть, я не делаю это в правильном направлении)

У меня есть AutoCompleteTextView и здесь я создал мою ПОДПИСКУ и наблюдаемые:

subcription = RxTextView.textChangeEvents(clearableEditText) 
       .skip(1) 
       .debounce(400, TimeUnit.MILLISECONDS) 
       .map(new Func1<TextViewTextChangeEvent, String>() { 
        @Override 
        public String call(TextViewTextChangeEvent textViewTextChangeEvent) { 
         return textViewTextChangeEvent.text().toString(); 
        } 
       }) 
       .filter(new Func1<String, Boolean>() { 
        @Override 
        public Boolean call(String s) { 
         return s.length() > 2; 
        } 
       }) 
       .flatMap(new Func1<String, Observable<List<String>>>() { 
        @Override 
        public Observable<List<String>> call(String text) { 
         return searchService.getAutoCompleteTermsObservable(text) 
           .subscribeOn(Schedulers.io()) 
           .observeOn(AndroidSchedulers.mainThread()); 
        } 
       }) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(new Subscriber<List<String>>() { 
        @Override 
        public void onCompleted() { 
         Log.d("rx", "oncomplete"); 
        } 

        @Override 
        public void onError(Throwable e) { 
         Log.e("rx", e.toString()); 
        } 

        @Override 
        public void onNext(List<String> strings) { 
         Log.d("rx", strings.size()+""); 
         autoAdapter = new ArrayAdapter<>(MainActivity.this, 
           android.R.layout.simple_dropdown_item_1line, strings); 
         clearableEditText.setAdapter(autoAdapter); 
         clearableEditText.showDropDown(); 
        } 
       }); 

Моя проблема в том, что я установил свой EditText с помощью метода setText(), он вызывает раскрывающееся меню. Например, он делает это, когда я устанавливаю слово из выпадающего списка AutoCompleteTextView и когда я устанавливаю его с помощью голосового ввода. Есть ли способ избежать запуска onTextChanged, когда я устанавливаю его вручную? Или как я могу это исправить?

+2

Проблема заключается в том, что при установке текста наблюдаемый испускает событие, пытается отказаться от подписки перед тем, как задать текст и подписаться снова после этого. – AndroidRuntimeException

+0

Да, просто! Спасибо @Agustin Sivoplás. –

+0

Рад помочь! Всего наилучшего! – AndroidRuntimeException

ответ

1

Вы действительно можете использовать unsubscribe(), но в зависимости от того, как вы установите значение, вы также используете skipWhile. Вот пример:

public void handleTextChanges() { 
    final String textFromSource = "an"; 

    Observable.fromArray("a", "an", "ancestor") 
      .skipWhile(new Predicate<String>() { 
       @Override 
       public boolean test(String value) throws Exception { 
        return textFromSource.contains(value); 
       } 
      }) 
      .subscribe(new Consumer<String>() { 
       @Override 
       public void accept(String value) throws Exception { 
        Log.d("Rx", value); 
       } 
      }); 
} 

Это будет только потреблять ancestor (пример RxJava2, но существуют одни и те же методы). Любые последующие значения, даже если они соответствуют an, будут потребляться. Вы можете использовать filter, если вы всегда хотите сделать чек, подобный этому

+0

Спасибо за альтернативный подход @ Джорди Ланген. Однако не делает ли этот запрос ненужным сетевым запросом? –

+0

Не так долго, как первое значение правды было сопоставлено в 'skipWhile' –

+0

Когда я выберу элемент из раскрывающегося списка AutoComplete, он вызовет setText с этим значением и потому что он вызывает onTextChange, он сделает только один запрос, чтобы получить предложения автозаполнения и с skipWhile, выпадающий список не будет показан. То же самое с голосовым вводом, я вызову setText, на этот раз он может или не может совпадать с этим, но также и в этих случаях выпадающее меню не будет отображаться. Да, на самом деле этот подход кажется более чистым, чем мой метод setTextSafely(). И я называю этот метод в нескольких местах, поэтому, если я хочу сделать автозаполнение пользовательским преимуществом, ваш путь даст мне гибкость. Спасибо, @Jordy Langen –

 Смежные вопросы

  • Нет связанных вопросов^_^