【问题标题】:What is the idiomatic way of refreshing using RxBinding on a SwipeRefreshLayout在 SwipeRefreshLayout 上使用 RxBinding 刷新的惯用方式是什么
【发布时间】:2017-09-30 08:47:19
【问题描述】:

我很难理解如何正确使用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 的目的。

或者我可以在swipeContaineronNext 中执行networkRequest。但它看起来像

       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】:

    你正在寻找这样的东西:

    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 的传入事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      相关资源
      最近更新 更多