简体   繁体   中英

AutoCompleteTextView with Retrofit 2, RxJava and RxBinding

I am new to Rx world and try to implement my AutoCompleteTextView with RxJava , RxBinding and Retrofit 2 .

Here's what I come up with which is troublesome: (Maybe I'm not doing it in the right way.)

I have an AutoCompleteTextView and here I created my subscribtion and observables:

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();
                    }
                });

My issue is when I set my EditText with setText() method, it triggers dropdown. For example it does that when I set the word from AutoCompleteTextView 's dropdown and when I set it with voice input. Is there a way to avoid triggering onTextChanged when I set it manually? Or how can I fix that?

You could indeed use unsubscribe() but depending on how you set the value, you also use skipWhile . Here is an example:

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);
                }
            });
}

This will only consume ancestor (example is RxJava2, but the same methods exist). Any subsequent values, even if they match an , will be consumed. You could use filter if you always want to do the check like this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM