在SwipeRefreshLayout上使用RxBinding刷新的惯用方法是什么?

问题描述 投票:0回答:1

我正在努力理解如何正确使用RxBinding,如果我想在用户向下刷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的目的。

或者我可以在networkRequestonNext执行swipeContainer。但那时看起来就像是

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

但是两次调用subscribe似乎就像反模式一样,所以是的,因为SwipeRefreshLayoutRxBinding库中,必须有一种惯用的方法,因为它似乎是最常见的用例。

android kotlin rx-java swiperefreshlayout rx-binding
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类似,但它将切换到新的可观察对象并丢弃来自previouse observable的事件。

© www.soinside.com 2019 - 2024. All rights reserved.