内容简介:在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很可能需要知道当前的异步数据操作是否正在进行(可以显示进度条),是否已经完成,或者是否失败。
一般我们可以能这样做:
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应用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Cookie的设置、读取以及是否自动携带问题
- Hasor 3.2.2 正式发布,携带了大量更新
- Spring Boot+Vue 文件上传,如何携带令牌信息?
- 警惕!你下载的软件可能携带STOP勒索病毒变种!
- javascript – 有可能使用angularJs将状态从状态传递到状态吗?
- 前端状态管理与有限状态机
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入浅出WebAssembly
于航 / 电子工业出版社 / 2018-11 / 128.00元
WebAssembly是一种新的二进制格式,它可以方便地将C/C++等静态语言的代码快速地“运行”在浏览器中,这一特性为前端密集计算场景提供了无限可能。不仅如此,通过WebAssembly技术,我们还可以将基于Unity等游戏引擎开发的大型游戏快速地移植到Web端。WebAssembly技术现在已经被计划设计成W3C的标准,众多浏览器厂商已经提供了对其MVP版本标准的支持。在Google I/O ......一起来看看 《深入浅出WebAssembly》 这本书的介绍吧!