本文部分资料来源于, Android 开放官方文档:Transformations
Transformations 是用于 LiveData 类的转换。
您可以使用转换方法在观察者的整个生命周期中传递信息。 除非观察者观察返回的 LiveData 对象,否则不计算转换。由于转换是延迟计算的,因此与生命周期相关的行为将隐式传递,而无需其他显式调用或依赖项。
一、map
LiveData<Y> map (LiveData<X> source,
Function<X, Y> func)
将主线程上的给定函数应用于 LiveData 数据源发出的每个值,然后返回 LiveData,来发出结果值。给定的函数 func 将在主线程上执行。
假设你有一个名为 userLiveData 的 LiveData,其中包含用户数据,并且你需要显示通过连接用户的名字和姓氏创建的用户名。 你可以定义一个处理名称创建的函数,该函数将应用于 useLiveData 发出的每个值。
LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
return user.firstName + " " + user.lastName
});
二、switchMap
LiveData<Y> switchMap (LiveData<X> trigger,
Function<X, LiveData<Y>> func)
创建一个 LiveData,将其命名为 swLiveData,它遵循以下流程:它对 trigger LiveData 的更改做出反应,将给定函数应用于 trigger LiveData 的新值,并将生成的 LiveData 设置为 swLiveData 的 “Backing” 的 LiveData。 “Backing” 的 LiveData 表示,它发出的所有事件都将由 swLiveData 重新传递。
如果给定的函数返回 null,则其他任何 LiveData 都不会 “backed” swLiveData。给定的函数 func 将在主线程上执行。
考虑具有包含用户 ID 的 LiveData 的情况。 每次发出新的用户 ID 时,你都想触发一个请求,从存储库中仍然返回的是 LiveData,去获得用户的对象与这个 ID 相对应。
userIdLiveData 是触发器,repository.getUserById 返回的 LiveData 是 “backing” LiveData。
在存储库包含 User(1,“ Jane”)和 User(2,“ John”)的情况下,当 userIdLiveData 值设置为“ 1”时,switchMap 将调用 getUser(1),这将返回一个 LiveData。 包含值 User(1,“ Jane”)。 因此,现在,userLiveData 将发出 User(1,“ Jane”)。 当存储库中的用户更新为 User(1,“ Sarah”)时,userLiveData 将自动得到通知,并发出 User(1,“ Sarah”)。
当使用 userId =“ 2” 调用 setUserId 方法时,userIdLiveData 的值将更改并自动触发从存储库获取 ID 为“ 2”的用户的请求。 因此,userLiveData 发出 User(2,“ John”)。 由repository.getUserById(1)返回的 LiveData 作为源数据被删除。
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id));
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
另外个 demo :
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import com.worldtech.jetpack.logic.MainPageRepository
import com.worldtech.jetpack.logic.api.MainPageService
import com.worldtech.jetpack.logic.model.Discovery
class DiscoveryViewModel(repository: MainPageRepository) : ViewModel() {
var dataList = ArrayList<Discovery.Item>()
private var requestParamLiveData = MutableLiveData<String>()
var nextPageUrl: String? = null
val dataListLiveData = Transformations.switchMap(requestParamLiveData) { url ->
liveData {
val resutlt = try {
val discovery = repository.refreshDiscovery(url)
Result.success(discovery)
} catch (e: Exception) {
Result.failure<Discovery>(e)
}
emit(resutlt)
}
}
fun onRefresh() {
requestParamLiveData.value = MainPageService.DISCOVERY_URL
}
fun onLoadMore() {
requestParamLiveData.value = nextPageUrl ?: ""
}
}
lifecycle 架构其他一些常用的点介绍:
LiveData<T>:
内容为 T 类型数据的容器,可监听内容的变化且具有一定的实时性;
对外提供监听容器内容变化的接口 observe(LifecycleOwner, Observer);
会在适当的时期通知监听器;
适当的时期:激活状态( LifecycleRegistry 监听 fragment 生命周期);
外部需 MutableLiveData 才能改变容器内容;
MutableLiveData:
继承至 LiveData;
提供改变容器内容的接口 setValue/postValue;
MediatorLiveData:
继承至MutableLiveData;
可监听其他容器内容的变化,通过 addSource(source:LiveData, Observer);
addSource 还需在激活状态下才会有机会调用 addSource 中的 Observer (激活后,source 才会添加 Observer 作监听器)
推荐一个官方文档的链接:
Android 开放官方文档:将 Kotlin 协程与架构组件一起使用
推荐一个:
采用 Jetpack + 协程实现的 MVVM 架构,用 Kotlin 写的短视频 Android 客户端项目
网友评论