在Android MVVM架構中,LiveData做爲通知UI更新的橋樑,地位極其重要,能夠說是MVVM的核心組件。git
在具體實踐中,它每每連接着對數據的異步操做結果。好比在登陸操做中,須要執行異步登陸邏輯,邏輯完成的結果會獲得用戶信息數據,這個數據可能會賦值給LiveData,用代碼表示以下:github
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層中。api
然而異步操做不是當即的,並且有進度,有狀態的。咱們的UI極可能須要知道當前的異步數據操做是否正在進行(能夠顯示進度條),是否已經完成,或者是否失敗。架構
通常咱們能夠能這樣作:異步
userVM.userData.observe(this, Observer{
if(it==null){
showFail() //顯示請求失敗
}else{
updateUI() //更新UI
}
})
showProgress() //登陸以前顯示進度條
userVM.login()
複製代碼
雖然咱們也能在代碼的某些地方去插入狀態展現,但這樣的寫法太過零碎,不易維護和管理。假設UI代碼有幾百行,你就會很難找到某個請求的進度條在哪裏寫着。post
若是每一個LiveData能攜帶本身的狀態,咱們就能夠面向LiveData來進行狀態更新,並且能在一個地方集中管理狀態,這樣就優雅的很。this
因而咱們能夠對LiveData進行擴展,增長一個state
字段,表明當前異步操做的狀態。因爲狀態應當是可監聽的,因此state
也是一個LiveData。代碼以下:spa
/** * 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層的代碼:code
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層對狀態的監聽變成了這樣:cdn
//統一管理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類庫中:github.com/li-xiaojun/… ,若是你用Kotlin開發Android,這個庫將可以大大提升你的開發速度。我是俊哥,致力於推動現代化的Android開發,用最佳的實踐,最優雅的代碼教你最快速的開發高質量Android應用。