如何以及在哪里使用 Transformations.switchMap?
How and where to use Transformations.switchMap?
最近 Android 由 Google 发布的架构组件库中,我们在 Transformations
class 中有两个静态函数。虽然 map
函数简单易懂,但我发现很难正确理解 switchMap
函数。
可以找到switchMap的官方文档here。
有人可以通过实际示例解释如何以及在何处使用 switchMap 函数吗?
在map()
函数中
LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
return user.firstName + " " + user.lastName; // Returns String
});
每当 userLiveData
的值发生变化时,userName
也会更新。请注意,我们正在返回 String
。
在switchMap()
函数中:
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id)); // Returns LiveData
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
每次userIdLiveData
的值改变时,repository.getUserById(id)
就会被调用,就像map函数一样。但是repository.getUserById(id)
returns一个LiveData
。因此,每当 repository.getUserById(id)
返回的 LiveData
的值发生变化时, userLiveData
的值也会发生变化。所以 userLiveData
的值将取决于 userIdLiveData
的变化和 repository.getUserById(id)
.
的值的变化
switchMap()
的实际示例:假设您有一个用户个人资料,其中包含一个关注按钮和一个设置另一个个人资料信息的下一个个人资料按钮。下一个配置文件按钮将使用另一个 ID 调用 setUserId(),因此 userLiveData
将更改并且 UI 将更改。关注按钮将调用 DAO 为该用户再添加一个关注者,因此该用户将拥有 301 个关注者而不是 300 个。userLiveData
将获得来自存储库的更新,该更新来自 DAO。
将我的 2 美分加到@DamiaFuentes 的回答中。
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id)); // Returns LiveData
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
Transformations.switchMap 方法只会在您至少有一个 userLiveData
观察者时被调用
对于那些想要对下面给出的@DamiaFuentes switchmap() 函数示例进行更多解释的人:
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id));
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
在存储库包含User(1, "Jane")和User(2, "John")的场景下,当userIdLiveData值设置为“1”时,switchMap会调用getUser (1),这将 return 一个包含值 User(1, "Jane") 的 LiveData。所以现在,userLiveData 将发出 User(1, "Jane")。当存储库中的用户更新为 User(1, "Sarah") 时,userLiveData 会自动收到通知并发出 User(1, "Sarah").
当调用 setUserId 方法并设置 userId = "2" 时,userIdLiveData 的值发生变化并自动触发从存储库中获取 ID 为 "2" 的用户的请求。因此,userLiveData 发出 User(2, "John")。由 repository.getUserById(1) 编辑的 LiveData return 作为来源被删除。
从这个例子中,我们可以了解到 userIdLiveData 是触发器,由 repository.getUserById 编辑的 LiveData return 是 "backing" LiveData。
更多参考,查看:https://developer.android.com/reference/android/arch/lifecycle/Transformations
传递给switchMap的函数returnsLiveData。当您的存储库本身 returns LiveData.
时使用它
还有一点要考虑选择 switchMap
还是 map
,你必须记住 map
总是将返回值包裹在 LiveData
周围,例如
fun getUser(id: Int): User
...
val userId = MutableLiveData(1)
val user = userId.map { // LiveData<User>
repository.getUser(it)
}
您可能会考虑使用 map
如果 repository.getUser(it)
returns 一个简单的 User
对象而不是 LiveData
这样用户类型就变成了 LiveData<User>
.
如果repository.getUser(it)
returns a LiveData<User>
那么最好使用switchMap
fun getUser(id: Int): LiveData<User>
...
val userId = MutableLiveData(1)
val user = userId.switchMap { // LiveData<User>
repository.getUser(it)
}
user
类型为 LiveData<User>
还有一点需要理解。
有人可能会想,因为我们总是在 switchMap() 中 return LiveData 的新值(新引用),所以我们如何在观察者只设置一次的情况下观察实际值?
重点是 Transformations.switchMap 的 returned 值是 MediatorLiveData,它将新的 LiveData 引用添加为新源(并停用其他源)。
最近 Android 由 Google 发布的架构组件库中,我们在 Transformations
class 中有两个静态函数。虽然 map
函数简单易懂,但我发现很难正确理解 switchMap
函数。
可以找到switchMap的官方文档here。
有人可以通过实际示例解释如何以及在何处使用 switchMap 函数吗?
在map()
函数中
LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
return user.firstName + " " + user.lastName; // Returns String
});
每当 userLiveData
的值发生变化时,userName
也会更新。请注意,我们正在返回 String
。
在switchMap()
函数中:
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id)); // Returns LiveData
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
每次userIdLiveData
的值改变时,repository.getUserById(id)
就会被调用,就像map函数一样。但是repository.getUserById(id)
returns一个LiveData
。因此,每当 repository.getUserById(id)
返回的 LiveData
的值发生变化时, userLiveData
的值也会发生变化。所以 userLiveData
的值将取决于 userIdLiveData
的变化和 repository.getUserById(id)
.
switchMap()
的实际示例:假设您有一个用户个人资料,其中包含一个关注按钮和一个设置另一个个人资料信息的下一个个人资料按钮。下一个配置文件按钮将使用另一个 ID 调用 setUserId(),因此 userLiveData
将更改并且 UI 将更改。关注按钮将调用 DAO 为该用户再添加一个关注者,因此该用户将拥有 301 个关注者而不是 300 个。userLiveData
将获得来自存储库的更新,该更新来自 DAO。
将我的 2 美分加到@DamiaFuentes 的回答中。
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id)); // Returns LiveData
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
Transformations.switchMap 方法只会在您至少有一个 userLiveData
观察者时被调用对于那些想要对下面给出的@DamiaFuentes switchmap() 函数示例进行更多解释的人:
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id));
void setUserId(String userId) {
this.userIdLiveData.setValue(userId);
}
在存储库包含User(1, "Jane")和User(2, "John")的场景下,当userIdLiveData值设置为“1”时,switchMap会调用getUser (1),这将 return 一个包含值 User(1, "Jane") 的 LiveData。所以现在,userLiveData 将发出 User(1, "Jane")。当存储库中的用户更新为 User(1, "Sarah") 时,userLiveData 会自动收到通知并发出 User(1, "Sarah").
当调用 setUserId 方法并设置 userId = "2" 时,userIdLiveData 的值发生变化并自动触发从存储库中获取 ID 为 "2" 的用户的请求。因此,userLiveData 发出 User(2, "John")。由 repository.getUserById(1) 编辑的 LiveData return 作为来源被删除。
从这个例子中,我们可以了解到 userIdLiveData 是触发器,由 repository.getUserById 编辑的 LiveData return 是 "backing" LiveData。
更多参考,查看:https://developer.android.com/reference/android/arch/lifecycle/Transformations
传递给switchMap的函数returnsLiveData。当您的存储库本身 returns LiveData.
时使用它还有一点要考虑选择 switchMap
还是 map
,你必须记住 map
总是将返回值包裹在 LiveData
周围,例如
fun getUser(id: Int): User
...
val userId = MutableLiveData(1)
val user = userId.map { // LiveData<User>
repository.getUser(it)
}
您可能会考虑使用 map
如果 repository.getUser(it)
returns 一个简单的 User
对象而不是 LiveData
这样用户类型就变成了 LiveData<User>
.
如果repository.getUser(it)
returns a LiveData<User>
那么最好使用switchMap
fun getUser(id: Int): LiveData<User>
...
val userId = MutableLiveData(1)
val user = userId.switchMap { // LiveData<User>
repository.getUser(it)
}
user
类型为 LiveData<User>
还有一点需要理解。 有人可能会想,因为我们总是在 switchMap() 中 return LiveData 的新值(新引用),所以我们如何在观察者只设置一次的情况下观察实际值? 重点是 Transformations.switchMap 的 returned 值是 MediatorLiveData,它将新的 LiveData 引用添加为新源(并停用其他源)。