将LiveData转换为可观察到的RxJava

时间:2019-08-12 14:50:07

标签: android rx-java android-livedata

我有2个视图:带有数量的EditText(不应为空)和协议复选框(应被选中)。我也有2个MutableLive数据变量,它们表示ViewModel内部此视图的状态。

我想在Observables中结合这两个变量,并使用Observable.combineLattest启用/禁用我的“发送”按钮。

我找到了一个名为android.arch.lifecycle:reactivestreams的库,并将LiveData转换为Publisher,但是我无法在Observable.combineLattest中使用它们,因为org.reactivestreams是因为Publisher是org.reactivestreams接口,并且Observable.combineLattest接受了可观察的源

我读了一些文章,但它们都引用了这个库。

目前我有这样的代码:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        ...

        dispossable = Observable.combineLatest(
                LiveDataReactiveStreams.toPublisher(this, vm.amount),
                LiveDataReactiveStreams.toPublisher(this, vm.isAgreementChecked),
                BiFunction<String, Boolean, Boolean> { amount, isChecked ->
                    amount.isNotEmpty() && isChecked
                })
    }

有人知道将LiveData转换为Observable的好方法。 预先感谢。

2 个答案:

答案 0 :(得分:0)

正如Blackbelt正确地说的那样,我可以将LiveData中的Flowable与以下内容结合使用:

LiveDataReactiveStreams.toPublisher(/*lifecycle*/, /*observable Field*/).

所以我当前的解决方案如下:

disposable = Flowable.combineLatest(
    LiveDataReactiveStreams.toPublisher(this, vm.amount),
    LiveDataReactiveStreams.toPublisher(this, vm.isAgreementChecked),
    BiFunction<String, Boolean, Boolean> { amount, isChecked ->
        amount.isNotEmpty() && isChecked
    }).subscribe { isDataValid ->
        vm.setIsDataValid(isDataValid)
    }

再次感谢:)

答案 1 :(得分:0)

一个替代解决方案可能是(我需要这样做,因为WorkManager仅返回LiveData):

fun getWorkData(): Flowable<List<WorkInfo>> {
    val workDataLiveData = WorkManager.getInstance().getWorkInfosByTagLiveData("TAG")
    Flowable.create({emitter -> 
        val observer = Observer> { emitter.onNext(it) }
        val disposable = disposeInUiThread { workDataLiveData.removeObserver(observer) }
        emitter.setDisposable(disposable)
        workDataLiveData.observeForever(observer)
    }, BackpressureStrategy.LATEST)
}

private fun disposeInUiThread(action: Action): Disposable {
        return Disposables.fromAction {
            if (Looper.getMainLooper() == Looper.myLooper()) {
                action.run()
            } else {
                val inner = AndroidSchedulers.mainThread().createWorker()
                inner.schedule {
                    try {
                        action.run()
                    } catch (e: Exception) {
                        Timber.e(e, "Could not unregister receiver in UI Thread")
                    }

                    inner.dispose()
                }
            }
        }
    }