使用 RxJava 在 RecyclerView 上更新 UI(加载和错误视图)

Update the UI ( Loading and Error Views ) on RecyclerView using RxJava

我有一个 SearchView,它执行网络请求来搜索一些曲目,然后用结果填充 RecylerView。我发现这段代码工作正常。

我已经通过 Adapter 集成了 RecyclerView EmptyView,但现在我正在尝试将 LoadingView(Progress) 和 ErrorView 集成到这段代码中。我试图将 LoadingView(ProgressBar) 置于 concatMap 内的 Visibility True 上,但出现“只有创建视图层次结构的原始线程才能触及其视图”的错误。这可以在 MainThread 上解决 运行 但我相信有更好的方法来做到这一点。

有人能更好地了解有关 show/hide ErrorView 和 LoadingView 的逻辑可以在何处以及如何集成到此代码中吗?

我也在使用 RxBinding。也许也使用 RxRecyclerView 是个好主意?

 RxSearchView.queryTextChanges(searchView).
            filter(charSequence ->
                    !TextUtils.isEmpty(charSequence))
            .throttleLast(100, TimeUnit.DAYS.MILLISECONDS)
            .debounce(200, TimeUnit.MILLISECONDS)
            .onBackpressureLatest()
            .concatMap(searchTerm ->
                    {



                        return  searchTracks(searchTerm).
                                .subscribeOn(Schedulers.io())
                                .onErrorResumeNext(throwable1 -> {
                                            //handle error somehow, change UI

                                            return Observable.empty();
                                        }

                                );

                    }
            )
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(tracks -> {


                populateTracks(tracks);

                    }
                });


            }, throwable -> {

            //show errorView


            });

这是我的完整解决方案,没有为演示文稿剥离代码。

RxSearchView.queryTextChanges(searchView)
    .skip(1)
    .doOnNext(charSequence -> Log.v(TAG, "searching: " + charSequence))
    .throttleLast(100, TimeUnit.MILLISECONDS)
    .debounce(200, TimeUnit.MILLISECONDS)
    .onBackpressureLatest()
    .observeOn(AndroidSchedulers.mainThread())
    .filter(charSequence -> {
        final boolean empty = TextUtils.isEmpty(charSequence);
        if (empty) {
            Log.v(TAG, "empty view");
            mAdapter.clear();
        }
        return !empty;
    })
    .concatMap(charSequence -> {
        Log.v(TAG, "requesting " + charSequence);
        return onErrorResumeNext(
                mGitApiService.searchRepositoriesSingle(charSequence.toString())
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread()),
                throwable -> {
                    try {
                        throw throwable;
                    } catch (HttpException httpException) {
                        showEmptyErrorView(httpException.message());
                    } catch (Throwable other) {
                        showEmptyErrorView(other.getMessage());
                        other.printStackTrace();
                    }
                    return Observable.empty();
                });
    })
    .doOnNext(charSequence -> Log.v(TAG, "got data"))
    .subscribe(response -> {
        showRepositories(response.getItems());
    }, throwable -> {
        throwable.printStackTrace();
        showEmptyErrorView(throwable.getMessage());
    });

所以基本上每当你触摸你的视图时,你都必须调用 .observeOn(AndroidSchedulers.mainThread())