如何从 Repository > ViewModel > Fragment 传播 Livedata

Ash*_*waj 5 kotlin android-livedata android-architecture-components

getMoreData() 在 ViewModel 中从 ViewModel 外部调用,每次用户滚动到 RecyclerView 的底部。

fetchMore()在 Repository 中返回一个LoadingStatus包含加载/成功/失败和错误消息的对象的 LiveData

如何loadingStatus在 ViewModel 中设置变量以便 Fragment 可以正确观察它?

注意:getMoreData()在 ViewModel 中可以在用户向下滚动时多次调用。

ViewModel{
    val loadingStatus

    fun getMoreData(){
        repository.fetchMore()
    }
}

Repository{
    fun fetchMore() : LiveData<LoadingStatus>{

    }
}

Fragment{
    viewModel.loadingStatus.observe()
}
Run Code Online (Sandbox Code Playgroud)

Bam*_*Bam 1

问题在于需要一个生命周期所有者来观察存储库中的 LiveData。

首先,您不想LiveData<LoadingStatus>每次fetchMore()调用时都返回一个新的。这将每次创建一个新的 LiveData。最好的情况是,您希望该函数fetchMore()执行类似这样的操作,更新单个 LiveData:

Repository{
    val status = LiveData<LoadingStatus>()

    fun fetchMore() {
        status.postValue(LOADING)

        // Pseudo code for actually loading more items

        status.postValue(FINISHED LOADING)
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,您将遇到观察的问题status,因为ViewModel它本身不是生命周期实现,因此它无法轻松地观察存储库中的 LiveData。

我的建议是这样的:

ViewModel{
    val loadingStatus: MutableLiveData<LoadingStatus>

    init{
        repository.observeStatus()
            .subscribe( event -> loadingStatus.postValue(event))
    }

    fun getMoreData(){
        repository.fetchMore()
    }
}

Repository{
    val status = BehaviorSubject.create<LoadingStatus>()

    fun observeStatus(): Observable<LoadingStatus> {
        return status
    }

    fun fetchMore(){
        status.onNext(LOADING)

        // Pseudo code for actually loading more items

        status.onNext(FINISHED LOADING)
    }
}

Fragment{
    viewModel.loadingStatus.observe()
}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须在 ViewModel onCleared 中处置订阅。
请注意,所有这些都是伪代码,应该比这更干净。