UI元素在观察订阅之前检查其状态

问题描述

我在更新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)
    }
}