简体   繁体   English

过滤器可观察 <List> 使用来自RxBinding的EditText中的文本

[英]Filter Observable<List> with text from an EditText using RxBinding

I have an array of Objects and I want to filter that array based on the text user types on an EditText android view. 我有一个对象数组,我想根据EditText android视图上的文本用户类型过滤该数组。

What I thought it that I should try and convert the array of POJOs to an Observable of Strings and this is what I did : 我认为应该尝试将POJO数组转换为字符串的Observable,这就是我所做的:

    Observable<String> professionsObservable = Observable.fromArray(((GetStartedActivity) getActivity()).professions)
            .map(profession -> {
                if (profession.getName().length() > 0) {
                    professionsNameList.add(capitalizeFirstLetter(profession.getName()));
                }

                return professionsNameList;
            })
            .flatMapIterable(items -> items);

Now I want to combine the text from the EditText with the `professionsObservable I posted above. 现在,我想将EditText的文本与我上面发布的`professionsObservable'相结合。

This is the code I'm using : 这是我正在使用的代码:

    RxTextView.textChangeEvents(etProfession)
            .doOnEach(notif -> {
                if (etProfession.getText().toString().trim().length() > 0) {
                    etCompany.setVisibility(GONE);
                    etIndustry.setVisibility(GONE);
                } else {
                    etCompany.setVisibility(VISIBLE);
                    etIndustry.setVisibility(VISIBLE);
                }
            })
            .debounce(EDITTEXT_DELAY, TimeUnit.MILLISECONDS)
            .skip(1)
            .map(textChangeEvent -> textChangeEvent.text().toString())
            .switchMap(search -> {
                return professionsObservable
                        .filter(profession -> {
                            return profession.toLowerCase().startsWith(search);
                        });
                    }
            )
            .toList()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    filteredProfessions -> {
                        Timber.i("NOT ENTERING");
                        rvProfession.setVisibility(VISIBLE);
                        professionAdapter.addItems(filteredProfessions);
                    },
                    throwable -> Log.i("THROW", "PROFESSIONS ", throwable));

I'm using map operator to turn the text change event to a String and then for each String I get from the stream I'm using switchMap (cause I don't care for results from previous searches). 我正在使用map运算符将文本更改事件转换为一个String,然后对于我使用switchMap从流中获取的每个String(因为我不在乎以前的搜索结果)。 Then I compose all Strings to a List with toList . 然后,我用toList所有字符串组成一个列表。 The problem is that it never reaches the subscribe call while I have a lot of strings in the initial Array I used and I do type text that fits the condition of the filter operator. 问题是,当我使用的初始数组中有很多字符串并且输入符合filter运算符条件的文本时,它永远不会到达subscribe调用。

Is it something that I might missing here ? 我在这里可能会想念的东西吗?

EDIT : I updated my code to : 编辑:我将代码更新为:

        RxTextView.textChangeEvents(etProfession)
            .doOnEach(notif -> {
                if (etProfession.getText().toString().trim().length() > 0) {
                    etCompany.setVisibility(GONE);
                    etIndustry.setVisibility(GONE);
                } else {
                    etCompany.setVisibility(VISIBLE);
                    etIndustry.setVisibility(VISIBLE);
                }
            })
            .subscribeOn(AndroidSchedulers.mainThread())
            .debounce(EDITTEXT_DELAY, TimeUnit.MILLISECONDS)
            .skip(1)
            .map(textChangeEvent -> textChangeEvent.text().toString())
            .flatMap(search -> {
                return Observable.fromArray(((GetStartedActivity) getActivity()).professions)
                        .map(profession -> {
                            List<String> professionsList = new ArrayList<>();
                            if (profession.getName().length() > 0) {
                                professionsList.add(capitalizeFirstLetter(profession.getName()));
                            }
                            return professionsList;
                        })
                        .flatMapIterable(items -> items)
                        .filter(profession -> {
                            if (profession.toLowerCase().startsWith(search.toLowerCase())) {
                            }

                            return profession.toLowerCase().startsWith(search.toLowerCase());
                        });
            })
            .toList()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    filteredProfessions -> {
                        rvProfession.setVisibility(VISIBLE);
             //        professionAdapter.addItems(filteredProfessions);
                    },
                    throwable -> Log.i("THROW", "PROFESSIONS ", throwable));

If I remove toList() operator my code works (enters the subscribe call) but if I leave it there it wont. 如果删除toList()运算符,我的代码将起作用(输入subscribe调用),但是如果我将其保留在那里,则不会。 Anyone knows why ? 有人知道为什么吗?

In my experience, RxBinding requires .subscribeOn(AndroidSchedulers.mainThread()) right after .textChangeEvents() or any other event. 以我的经验, RxBinding.textChangeEvents()或任何其他事件之后需要.subscribeOn(AndroidSchedulers.mainThread()) So probably you are causing it to fail by adding .subscribeOn(Schedulers.io) 所以可能是通过添加.subscribeOn(Schedulers.io)导致其失败

See method .checkMainThread() in https://github.com/JakeWharton/RxBinding/blob/master/rxbinding/src/main/java/com/jakewharton/rxbinding2/internal/Preconditions.java 请参阅https://github.com/JakeWharton/RxBinding/blob/master/rxbinding/src/main/java/com/jakewharton/rxbinding2/internal/Preconditions.java中的方法.checkMainThread()

UPDATE 更新

Also, probably because .onComplete() never comes from upstream, .toList() is never executed. 另外,可能是因为.onComplete()永远不会来自上游, 所以永远不会执行.toList()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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