带有RxJava的ArrayAdapter getFilter()

时间:2018-01-31 03:48:38

标签: java android rx-java android-arrayadapter rx-android

我的活动中有一个SearchView,并添加了onQueryTextChange个侦听器。 我还添加了扩展Filter类的自定义类。在那里我添加了RxJava观察者,你可以在下面的代码中看到。但问题是我必须从类中返回FilteretedResults但是RxJava的观察者onComplete方法的返回类型是无效的。所以我的过滤结果总是为空并且崩溃了应用程序,因为我正在使用过滤结果做一些事情。如果我想在后台进行字符串匹配,那么这样做的正确方法是什么,因为列表包含大约2500条记录而不会阻止UI?

private class ValueFilter extends Filter {

    @Override
    protected FilterResults performFiltering(final CharSequence charSequence) {
        final FilterResults filterResults=new FilterResults();
        final List<SubCategorySingle> subCategorySinglesLocal=new ArrayList<>();

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext(charSequence+"");
            }
        })
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String s) {

                if(charSequence !=null && charSequence.length()>0){
                    for(int i=0;i<subCategoryList.getSubCategorySingles().size();i++){
                        if(subCategoryList.getSubCategorySingles().get(i).getName().toUpperCase().contains(charSequence.toString().toUpperCase())){
                            subCategorySinglesLocal.add(subCategoryList.getSubCategorySingles().get(i));
                        }
                    }
                    filterResults.count=subCategorySinglesLocal.size();
                    filterResults.values=subCategorySinglesLocal;
                }else{
                    filterResults.count=subCategoryList.getSubCategorySingles().size();
                    filterResults.values=subCategoryList.getSubCategorySingles();
                }

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                filterResults.notifyAll();
            }
        });

        return filterResults;

    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        setupCategoryForSearch((List<SubCategorySingle>)filterResults.values);
    }
}

private void setupCategoryForSearch(List<SubCategorySingle> values) {
    catHolder.removeAllViews();
    progressBar.smoothToShow();
    for(int i=0;i<values.size();i++){
        addCategory(values.get(i));
    }
    progressBar.smoothToHide();
}

1 个答案:

答案 0 :(得分:0)

Filter#performFiltering(CharSequence)的文档中所示:

  

在工作线程中调用根据约束过滤数据。子类必须实现此方法才能执行过滤操作。过滤操作计算的结果必须作为Filter.FilterResults返回,然后将在UI线程中通过publishResults(CharSequence, android.widget.Filter.FilterResults)发布。

因此,默认情况下,performFiltering()将在后台线程上运行,您将获得开箱即用的功能,无需通过Rx方法在后台线程上执行长时间运行的操作(在事实上你甚至不能这样做,因为ArrayAdapter的API确实提供这样的能力。)