1

我正在努力理解如何正确使用RxBinding,如果我想在用户向下滑动 a 时调用网络请求SwipeRefreshLayout,我希望说类似的话

    RxSwipeRefreshLayout.refreshes(swipeContainer)
            .flatMap { networkRequest() }
            .subscribeBy(
                    onNext = { list: List<Data> -> Timber.d(data) },
                    onError = { showErrorSnackbar(it) },
                    onComplete = { Timber.d("On Complete") })

但这对我不起作用,因为我将它包装在一个调用的函数setupSwipeRefresh()中,我调用它onStart,所以一旦onStart调用网络请求就会发出,因为那是订阅布局的时候。

现在我不确定该怎么做。我可以把整个东西都放进去,refreshListener但这违背了RxBinding.

或者我可以执行networkRequest. 但它看起来像onNextswipeContainer

       RxSwipeRefreshLayout.refreshes(swipeContainer)
            .subscribeBy(
                    onNext = {
                        networkRequest()
                                .subscribeBy(
                                        onNext = { list: List<Data> ->
                                            Timber.d(data)
                                        })
                    },
                    onError = { showErrorSnackbar(it) },
                    onComplete = { Timber.d("On Complete") })

但是两次调用 subscribe 似乎是一种反模式,所以是的,因为SwipeRefreshLayoutRxBinding库中,所以必须有一种惯用的方式来执行此操作,因为它似乎是最常见的用例。

4

1 回答 1

0

你正在寻找这样的东西:

SwipeRefreshLayout viewById = findViewById(R.id.activity_main_swipe_refresh_layout);

Observable<State> swipe = RxSwipeRefreshLayout.refreshes(viewById)
        .map(o -> new IsLoading());

Observable<State> stateObservable = Observable.<State>just(new IsLoading())
        .mergeWith(swipe)
        .switchMap(state -> Observable.concat(
                Observable.just(new IsLoading()),
                Observable.<State>timer(500, TimeUnit.MILLISECONDS)
                        .map(aLong -> new LoadingResult(Collections.emptyList())
                        )
                )
        ).distinct();

stateObservable
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
                state -> {
                    if (state instanceof IsLoading) {
                        Log.d("state", "isLoading");
                    } else if (state instanceof LoadingResult) {
                        Log.d("state", "loadingResult");
                        viewById.setRefreshing(false);
                    }
                });

活动

interface State { }

class IsLoading implements State { }

class LoadingResult implements State {
    private final List<String> result;
    public LoadingResult(List<String> result) {
        this.result = result;
    }
}

SwitchMap 类似于 FlatMap,但它会切换到新的 observable 并丢弃来自先前 observable 的传入事件。

于 2017-10-03T09:43:12.413 回答