携带状态的LiveData

栏目: Android · 发布时间: 5年前

内容简介:在Android MVVM架构中,LiveData作为通知UI更新的桥梁,地位极其重要,可以说是MVVM的核心组件。在具体实践中,它往往链接着对数据的异步操作结果。比如在登录操作中,需要执行异步登录逻辑,逻辑完成的结果会得到用户信息数据,这个数据可能会赋值给LiveData,用代码表示如下:这样的代码会大量出现在我们的VM层中。

在Android MVVM架构中,LiveData作为通知UI更新的桥梁,地位极其重要,可以说是MVVM的核心组件。

在具体实践中,它往往链接着对数据的异步操作结果。比如在登录操作中,需要执行异步登录逻辑,逻辑完成的结果会得到用户信息数据,这个数据可能会赋值给LiveData,用代码表示如下:

class UserVM : ViewModel() {
    val userData = MutableLiveData<User>()
    
    fun login(){
        viewModelScope.launch { 
            val result = "http://www.lixiaojun.xin/api/login".http().post<User>().await()
            userData.postValue(result)
        }
    }
}
复制代码

这样的代码会大量出现在我们的VM层中。

问题

然而异步操作不是立即的,而且有进度,有状态的。我们的UI很可能需要知道当前的异步数据操作是否正在进行(可以显示进度条),是否已经完成,或者是否失败。

携带状态的LiveData

一般我们可以能这样做:

userVM.userData.observe(this, Observer{ 
    if(it==null){
        showFail() //显示请求失败
    }else{
        updateUI() //更新UI
    }
})
showProgress() //登录之前显示进度条
userVM.login() 

复制代码

虽然我们也能在代码的某些地方去插入状态展示,但这样的写法太过零碎,不易维护和管理。假设UI代码有几百行,你就会很难找到某个请求的进度条在哪里写着。

如果每个LiveData能携带自己的状态,我们就可以面向LiveData来进行状态更新,而且能在一个地方集中管理状态,这样就优雅的很。

实现

于是我们可以对LiveData进行扩展,增加一个 state 字段,代表当前异步操作的状态。由于状态应当是可监听的,所以 state 也是一个LiveData。代码如下:

/**
 * Description: 携带状态的LiveData
 * Create by lxj, at 2019/3/6
 */
class StateLiveData<T> : MutableLiveData<T>() {

    enum class State {
        Idle, Loading, Success,Error
    }
    val state = MutableLiveData<State>()

    init {
        clearState()
    }

    fun postValueAndSuccess(value: T) {
        super.postValue(value)
        postSuccess()
    }

    fun clearState() {
        state.postValue(State.Idle)
    }

    fun postLoading() {
        state.postValue(State.Loading)
    }

    fun postSuccess() {
        state.postValue(State.Success)
    }

    fun postError() {
        state.postValue(State.Error)
    }

    fun changeState(s: State) {
        state.postValue(s)
    }
}
复制代码

我们使用StateLiveData改写VM层的代码:

class UserVM : ViewModel() {
    val userData = StateLiveData<User>()
    fun login(){
        viewModelScope.launch {
            userData.postLoading()
            val result = "http://www.lixiaojun.xin/api/login".http().post<User>().await()
            if(result==null){
                userData.postError()   
            }else{
                userData.postValueAndSuccess(result)
            }
        }
    }
}
复制代码

而此时UI层对状态的监听变成了这样:

//统一管理LiveData的状态
userVM.userData.state.observe(this, Observer{ 
    when(it){
        StateLiveData.State.Loading -> showProgress()
        StateLiveData.State.Error -> showFail()
        //...其他状态处理
    }
})
userVM.userData.observe(this, Observer{ 
    updateUI() //直接更新UI
})
userVM.login() 
复制代码

推荐

上面的StateLiveData被内置在我的AndroidKTX类库中,如果你用Kotlin开发Android,这个库将能够大大提高你的开发速度。我是俊哥,致力于推进现代化的Android开发,用最佳的实践,最优雅的代码教你最快速的开发高质量Android应用。

携带状态的LiveData

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

啊哈C!思考快你一步

啊哈C!思考快你一步

啊哈磊 / 电子工业出版社 / 2013-9 / 39.00元

这是一本非常有趣的编程启蒙书,全书从中小学生的角度来讲述,没有生涩的内容,取而代之的是生动活泼的漫画和风趣幽默的文字。并配合超萌的编程软件,从开始学习与计算机对话到自己独立制作一个游戏,由浅入深地讲述编程的思维。同时,与计算机展开的逻辑较量一定会让你觉得很有意思。你可以在茶余饭后阅读本书,甚至蹲在马桶上时也可以看得津津有味。编程将会改变我们的思维,教会我们如何思考,让我们的思维插上计算机的翅膀,以......一起来看看 《啊哈C!思考快你一步》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具