持续关于方向变化的对话框的视图状态

时间:2018-01-30 07:50:08

标签: android android-dialog android-architecture-components

在我当前的Android项目中,我有一个对话框,用于从Web服务中检索对象列表并在列表中显示这些对象。但它有一个问题。 Web服务(在我的控制范围之外)并不是最快的,因此该过程需要一段时间,并且通常用户在此过程正在进行时更改设备的方向。现在,方向更改会导致原始webservice调用被取消并创建一个新的调用,但这不是我应该知道的。我希望对话框能够在方向更改发生时继续从Web服务加载,但我无法理解如何执行此操作。如何挂钩正在进行的调用并在视图(对话框)中显示此状态?任何建议表示赞赏。我已经玩过Android架构组件和kotlins密封类,将视图状态保存在视图观察到的一个livingata对象中,但是没有找到我喜欢的解决方案。

我相信很多开发人员都会使用RxJava来解决这类问题。这是我唯一的选择吗?

顺便说一下。目前我在我的项目中使用MVP架构。

修改

这是我取消作业的地方 - 如果收听者为空,则取消(我使用kotlin协同程序):

override fun getWorklist() {
    job = onWorkerThread {
        val result = repository.getResult().awaitResult()
        onMainThread {
            when (result) {
                is Result.Ok -> listener?.onResult(result.getOrDefault(emptyList())) :? job.cancel()
                // Any HTTP error
                is Result.Error -> listener?.onHttpError(result.exception) :? job.cancel()
                // Exception while request invocation
                is Result.Exception -> listener?.onException(result.exception) :? job.cancel()
            }
        }
    }
}

修改2

我已尝试使用此Android Arch ViewModel控制viewstate,但未在viewstate对象更改时触发MediatorLiveData对象。视图保持加载状态:

class MainModel : ViewModel() {

    private var job: Job? = null

    val viewState = MutableLiveData<MainViewState>().apply { value = Loading("Warsaw") }

    val dataGetter = MediatorLiveData<MainViewState>().apply {
        addSource(viewState, {
            Log.d("MainModel", "Viewstate is: " + viewState.value.toString() + ")...")
            when(it) {
                is Loading -> {
                    Log.d("MainModel", "Launching coroutine...")
                    job = launch(UI) {
                        Log.d("MainModel", "Loading...")
                        val items = Repository.getWorklist()
                        Log.d("MainModel", "Charts retrieved...")
                        this@MainModel.viewState.postValue(Success(it.items))
                        Log.d("MainModel", "Posted update to viewstate...")
                    }
                }
            }
        })
    }

    override fun onCleared() {
        Log.d("MainModel", "Clearing ViewModel")
        job?.cancel()
    }
}

interface ViewState

sealed class MainViewState : ViewState
class Loading() : MainViewState()
class Error(val error: String) : MainViewState()
class Success(val items: List<WorklistItem>) : MainViewState()

0 个答案:

没有答案