问题描述
我在更新Android应用中的刷新按钮状态时遇到问题。在我的交互器内部,我有一对主题来控制刷新按钮的状态。
class PageInteractor {
private var isRefreshActionEnabled = false
private val refreshStatePublisher by lazy {
BehaviorSubject.create<Boolean>().apply {
onNext(false)
}
}
private var refreshActionPublisher: PublishSubject<Unit>? = null
fun observeRefreshButtonState(): Observable<Boolean> {
return refreshStatePublisher
}
fun observeRefreshAction(): Observable<Unit> {
if (refreshActionPublisher?.hasComplete() == false && refreshActionPublisher?.hasObservers() == true) {
refreshActionPublisher?.onComplete()
}
return PublishSubject.create<Unit>()
.also {
refreshActionPublisher = it
updateRefreshButtonState()
}
.doOndispose {
updateRefreshButtonState()
}
}
fun setRefreshActionEnabled(value: Boolean) {
if (isRefreshActionEnabled != value) {
isRefreshActionEnabled = value
updateRefreshButtonState()
}
}
fun onRefreshAction() {
refreshActionPublisher?.onNext(Unit)
}
private fun updateRefreshButtonState() {
refreshStatePublisher.onNext(refreshActionPublisher?.hasComplete() == false
&& refreshActionPublisher?.hasObservers() == true)
}
}
我在演示者中使用此交互器,它是Moxy演示者。
class PagePresenter(
private val pageInteractor: PageInteractor
) : MvpPresenter<PageView> {
override fun onFirstViewAttach() {
super.onFirstViewAttach()
pageInteractor
.observeRefreshButtonState()
.subscribe { isEnabled ->
viewState.setRefreshButtonEnabled(isEnabled)
}
.addTo(disposable)
}
fun onRefreshButtonClicked() {
pageInteractor.onRefreshAction()
}
}
我的问题是打开页面时禁用了刷新按钮。我进行了一些调试,看来方法observeRefreshAction
中问题的根源。设置PublishSubject
时,此方法创建refreshActionPublisher
,此后立即调用方法updateRefreshButtonState
。此方法通过调用PublishSubject
来检查hasObservers
是否有任何订阅者,并且结果几乎总是为false。发生这种情况是因为PublishSubject
尚未返回给演示者,我可以在其中订阅。
有什么办法可以解决此问题?我曾尝试将updateRefreshButtonState
移至doOnSubscribe
,但这没有帮助。
解决方法
我试图理解问题,并编写了一些代码并添加了一些注释。
因此,您不需要额外的“发布主题”即可调用操作,只需调用onRefreshAction()
并更改refreshButtonState的当前状态即可。
import io.reactivex.Observable
import io.reactivex.subjects.BehaviorSubject
import kotlin.random.Random
class PageInteractor {
// Initial value is false and after subscription,subscriber will receive that value
private val refreshButtonState = BehaviorSubject.createDefault(false)
fun observeRefreshButtonState(): Observable<Boolean> = refreshButtonState.distinctUntilChanged()
// Invoke refresh action
fun onRefreshAction() {
// Change state or toggle state or something else
// Currently generate random next state
val nextAction = Random.nextBoolean()
refreshButtonState.onNext(nextAction)
}
}