携带状态的LiveData

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

内容简介:在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

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

查看所有标签

猜你喜欢:

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

淘宝十年产品事

淘宝十年产品事

苏杰 / 电子工业出版社 / 2013-10-15 / 55.00

产品经理发展到一定阶段,再要成长,光靠学习一些知识、技能已经不够,必须通过经典案例来学习,而本书,就提供了小到页面细节、大到平台架构的丰富案例。电商从业者,无法无视“淘宝”这个标杆的存在,本书可帮助大家做出更好的选择。愿意思考的人们,也可以从“淘宝”这个产品,或者说社会 现象、经济现象里,找到每天都能体会到的那些变化的原因,从而想得更明白,活得更通透。 本书细数淘宝成立十年来经历的重大变化,......一起来看看 《淘宝十年产品事》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具