如何以及在何处使用Transformations.switchMap?

Eht*_*san 36 android android-livedata android-architecture-components

在Google最近发布的Android Architecture Components库中,我们在Transformations类中有两个静态函数.虽然map功能很直接且易于理解,但我发现很难正确理解该switchMap功能.

可以在此处找到switchMap的官方文档.

有人可以用一个实际的例子解释如何以及在哪里使用switchMap功能?

Dam*_*tes 68

map()功能

LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
     return user.firstName + " " + user.lastName; // Returns String
});
Run Code Online (Sandbox Code Playgroud)

每次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);
}
Run Code Online (Sandbox Code Playgroud)

每次userIdLiveData更改的值,repository.getUserById(id)都会被调用,就像map函数一样.但是repository.getUserById(id)返回一个LiveData.所以每当LiveData返回repository.getUserById(id)的值发生变化时,其值userLiveData也会发生变化.所以价值userLiveData取决于价值的变化userIdLiveData和变化repository.getUserById(id).

实际示例switchMap():假设您有一个带有跟随按钮的用户配置文件和一个设置另一个配置文件信息的下一个配置文件按钮.下一个配置文件按钮将使用另一个id调用setUserId(),因此userLiveData将更改并且UI将更改.按下按钮将调用DAO以向该用户添加一个关注者,因此用户将拥有301个关注者而不是300个.userLiveData将来自存储库的此更新来自DAO.

  • 转换的一些架构背景,它们在 ViewModel 中最常用,因为它允许将来自 DAO 的数据类型转换为需要在 UI 上显示的类型,因此,假设您有添加到购物车功能,您将向购物车添加元素,假设此购物车是一个哈希图,它将每个产品 id 与列表中的一个项目相对应,此哈希图来自 DAO,但我们不是将此哈希图传递到 UI,而是使用转换来将此 hashmap 转换为友好列表以在 UI 中显示,现在 HashMap<String,Cart> 将转换为 List<Cart> (4认同)

Pra*_*ash 15

将我的2美分加到@DamiaFuentes的答案中.

MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id)); // Returns LiveData

void setUserId(String userId) {
     this.userIdLiveData.setValue(userId);
}
Run Code Online (Sandbox Code Playgroud)

只有至少有一个userLiveData观察者时,才会调用Transformations.switchMap方法

  • 我曾经是一个简单的人。当我无法理解这个概念时,我就自己做了一些东西。在本例中,我使用自定义数据源、构建器等创建了整个类,直到我遇到了心理障碍。你的回答让我再次成为一个简单的人。我删除了那个类。 (6认同)
  • 非常感谢@Prakash,我一直在努力找出为什么我的 switchMap 没有监听触发器的变化。 (3认同)

Son*_*eev 7

对于那些想要对@DamiaFuentes switchmap()函数示例进行更多说明的人,请参见以下示例:

 MutableLiveData userIdLiveData = ...;
 LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
     repository.getUserById(id));

 void setUserId(String userId) {
      this.userIdLiveData.setValue(userId);
 }
Run Code Online (Sandbox Code Playgroud)

在存储库包含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作为源被删除。

从此示例中,我们可以了解到userIdLiveData是触发器,而repository.getUserById返回的LiveData是“支持” LiveData。

有关更多参考,请查看:https : //developer.android.com/reference/android/arch/lifecycle/Transformations


sno*_*lax 5

传递给 switchMap 的函数返回 LiveData。当您的存储库本身返回 LiveData 时使用它。