2016-11-13 170 views
2

我是新来Rx世界,并试图实现我AutoCompleteTextViewRxJavaRxBindingRetrofit 2AutoCompleteTextView与改造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(); 
        } 
       }); 

我的问题是当我用setText()方法设置我的EditText时,它会触发下拉菜单。例如,当我从AutoCompleteTextView的下拉菜单中设置单词时,以及当我使用语音输入设置单词时。当我手动设置时,是否有办法避免触发onTextChanged?或者我该如何解决这个问题?

+2

的问题是检查,当你设置的文本时,可观察到发射的情况下,尝试退订设置文本之前,之后重新订阅。 – AndroidRuntimeException

+0

是的,就这么简单!谢谢@AgustinSivoplá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

感谢您的替代方法@Jordy Langen。但是,这不是一个不必要的网络要求吗? –

+0

只要不是第一truthy值在'skipWhile' –

+0

被匹配当我从自动完成下拉列表中选择项目时,它会叫的setText与价值,因为它触发onTextChange,它会让只有一个请求得到自动完成建议和skipWhile,下拉将不会显示。与语音输入一样,我会调用setText,这次它可能会或可能不会匹配,但在这些情况下,下拉将不会显示。是的,实际上,这种方法似乎比我的setTextSafely()方法更干净。我在几个地方调用了这个方法,所以如果我想让自动填充用户界面,你的方式会给我灵活性。谢谢,@Jordy Langen –