将LiveData <List>有效转换为另一个LiveData <List>

问题描述

考虑一些存储在Room数据库中的通用@Entity User。某些@Dao重新运行LiveData<List<User>>又名'dao结果'。我希望创建另一个 live 列表,其中每个元素都是dao结果的转换,例如

LiveData<List<UserWrapper>>

//UserWrapper needs a User to construct

所以我写类似

 Transformations.map(daoResult,list -> {

            
            List<UserWrapper> newList=new ArrayList<>(list.size());
            list.forEach(user -> {
               newList.add(new UserWrapper(user));
            });

            return newList;
        });

如果我对LiveData的理解是正确的,则dao结果仅响应List级别的更改,例如,将列表添加到列表中,从列表中减去等,如果底层User对象是或其字段更改,则不行。

  1. 这正确吗?

说在数据库中进行了一些更改,这些更改使一些新记录符合基础dao结果的@Query

的结果集中的条件
  1. 查询结果LiveData<List<User>>是否会自动反映出来? Transformations.map会带到LiveData<List<UserWrapper>>吗?

在上述实现中,每次修改底层的 list 时,地图都会创建一个新的List并将其重新初始化,这在我看来似乎是效率低下并且是某种错误。为什么必须手动检查两个列表以确保有效的转换状态?

  1. 是否有更好的方法可以使UserUserWrapper之间始终保持1-1对应?

解决方法

我不确定我是否明白你的问题,但请考虑一下我的想法:

  1. 使用LiveData作为查询的返回类型时,Room为您设置了某种回调。因此,如果您在查询中使用select * from users ...,则对表users的每次更改都会触发更新LiveData的值(这并不明显,所以我的意思是-即使某些用户已被更改,但EACH仍在更改中您的结果列表)。
  2. 理论上,您不仅可以从查询到表user,还可以到表List<User>。它取决于List<UserWrapper>UserWrapper结构。为此,您应该使用与User字段匹配的字段或使用Room's Relations来编写查询。