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

Ken*_*ele 1 android rx-java retrofit rx-android android-recyclerview

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

我已经通过适配器集成了RecyclerView EmptyView,但现在我正在尝试在此代码中集成LoadingView(Progress)和ErrorView.我试图在ConcatMap中将LoadView(ProgressBar)放在Visibility True上但是得到的错误是"只有创建视图层次结构的原始线程可以触及它的视图."这可以解决在MainThread上运行它但我确定有一个更好的方法来做到这一点.

有人可以更好地了解显示/隐藏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


            });
Run Code Online (Sandbox Code Playgroud)

pas*_*ssy 9

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

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());
    });
Run Code Online (Sandbox Code Playgroud)

所以基本上每当你触摸你的视图时你都要打电话 .observeOn(AndroidSchedulers.mainThread())

  • **所以基本上每当你触摸你的视图时,你必须调用 .observeOn(AndroidSchedulers.mainThread())** 部分应该突出显示,因为这是最重要的事情。基本上,你在处理彼此时应该在同一个线程中。这种情况去抖动位于计算线程中,但视图在主线程中。 (2认同)