如果你使用 Jetpack 中还没踩过这些坑,请务必收下这篇文章
}
这里通过 ViewModelProviders 来获取 ViewModelProvider 在通过 get 方法来获取 ViewModel 实例。我们通过 button 按钮注册了一个点击事件来模拟数据源数据的更新。
数据转换
如果我们想对从服务端获取
到的数据进行修改可以使用 Transformations 操作符。分为 Map 和 switchMap 两种。switchMap 需要返回一个 LiveData 对象。
Transformations.map
Transformations.map(secondViewModel.userData, object : Function<UserInfo, UserInfo> {override fun apply(userInfo: UserInfo): UserInfo {userInfo.name = "张三"return userInfo}
}).observe(this, Observer {mTvShow.text = "姓名:{it.salary}"})
这就将 name 重新赋值为“张三”。
Transformations.switchMap
比如我们有些数据需要依赖其他数据进行查询,就可以使用 switchMap。
Transformations.switchMap(secondViewModel.userData, object : Function<UserInfo, LiveData<UserInfo>> {override fun apply(userInfo: UserInfo): LiveData<UserInfo> {return secondViewModel.getUserName(userInfo)}}).observe(this, Observer {mTvShow.text = "姓名:{it.salary}"})
在 ViewModel 中定义 getUserName 方法
fun getUserName(userInfo: UserInfo): LiveData<UserInfo> {userInfo.name = userInfo.name + "switchMap"switchMapData.value = userInforeturn switchMapData}
MediatorLiveData
当我们页面需要多个不同的数据源的时候,如果我们都是单独的使用 LiveData,会导致 Activity 中定义很多 observe,出现很多多余的代码。MediatorLiveData 就为解决这个问题的。它可以将多个 LiveData 合并在一起,只需要定义一次 observe 就可以。
var data1: MutableLiveData<UserInfo> = MutableLiveData()var data2: MutableLiveData<UserInfo> = MutableLiveData()var mediatorLiveData: MediatorLiveData<UserInfo> = MediatorLiveData()
val user1 = UserInfo("李四 1", (1000..5000).random())val user2 = UserInfo("李四 2", (1000..5000).random())
data1.postValue(user1)data2.postValue(user2)
mediatorLiveData.addSource(data1, object : Observer<UserInfo> {override fun onChanged(info: UserInfo) {mediatorLiveData.value = info}
})
mediatorLiveData.addSource(data2, object : Observer<UserInfo> {override fun onChanged(info: UserInfo) {mediatorLiveData.value = info}
})
这个我们定义了两个 MutableLiveData 表示正常的数据获取。MediatorLiveData 通过 addSource 方法将 data1 和 data2 合并一起组成新的 LiveData。onChanged 回调表示的是当 data1 和 data2 数据源数据发送变化的时候进行回调。通知界面 UI 进行数据刷新。
我们在 Activity 中使用:
secondViewModel.mediatorLiveData.observe(this, Observer {if (it.name.contains("1")) {mTvShow.text = "姓名:{it.salary}"} else {mTvShowOther.text = "姓名:{it.salary}"}
})
这里就简单的通过 name 来判断不同的数据源类型。这样就将 data1 和 data2 首次请求的数据在界面展示了。上文也讲了 onChanged 是监听 data1 和 data2 数据变化的。这里我们在 XML 布局文件中新加一个 button 按钮用来模拟数据源变化。
然后在 ViewModel 中第一模拟刷新方法:
/**
模拟 data1 和 data2 数据源改变*/fun update() {
val updateUser1 = UserInfo("李四 1 update", (1000..5000).random())val updateUser2 = UserInfo("李四 2 update", (1000..5000).random())
data1.postValue(updateUser1)data2.postValue(updateUser2)
}
postValue 执行完成后 onChanged 方法将接受到回调并通知 UI 更新数据。
扩展 LiveData
如果观察者的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 认为观察者处于活动状态。如果我们知道什么时候是 active 和 inactive,那么我们可以自己实现 LiveDta。所以 LiveData 提供了两个方法,分别为 onActive()与 onInactive()。并给出了官方 Demo:
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {private val stockManager = StockManager(symbol)
private val listener = { price: BigDecimal ->value = price}
override fun onActive() {stockManager.requestPriceUpdates(listener)}
评论