【发布时间】:2020-05-31 17:37:35
【问题描述】:
目前,我们在 Room SQLite 中存储了一个数据结构,名为Todo
我们目前的工作流程如下
- Dao 正在返回
DataSource.Factory<Integer, Todo> - 使用
LivePagedListBuilder将DataSource.Factory<Integer, Todo>变成LiveData<PagedList<Todo>> - 观察
LiveData<PagedList<Todo>>,并使用submitList将PagedList<Todo>传递给PagedListAdapter<Todo, TodoAdapter.ViewHolder>
到目前为止,对于这种简单的用例来说非常好。
但是,现在,我们有一个更复杂的 UI 要求。我们需要将Todo 转换为TransformedTodo,然后将submitList 转换为PagedListAdapter。
这是我们的变换函数。
List<TransformedTodo> transform(Todo todo)
注意,可以将 1 个 Todo 转换为 1 个或多个 TransformedTodo。
我最初计划的工作流程是
- 道正在返回
DataSource.Factory<Integer, Todo> - 使用
DataSource.Factory.mapByPage,将DataSource.Factory<Integer, Todo>转换为DataSource.Factory<Integer, TransformedTodo> - 使用
LivePagedListBuilder将DataSource.Factory<Integer, TransformedTodo>变成LiveData<PagedList<TransformedTodo>> - 观察
LiveData<PagedList<TransformedTodo>>,并使用submitList将PagedList<TransformedTodo>传递给PagedListAdapter<TransformedTodo, TodoAdapter.ViewHolder>
棘手的部分是第 2 步。
如果转换函数返回输出List<TransformedTodo>,其大小与输入List<Todo>不同,则会抛出异常。
todosDataSourceFactory.mapByPage(new Function<List<Todo>, List<TransformedTodo>>() {
@Override
public List<TransformedTodo> apply(List<Todo> input) {
// Exception will be thrown if we are returning a List where its size is different from input.
}
});
抛出的异常看起来像
java.lang.IllegalStateException: 无效函数 com.yocto.wetodo.repository.TodoRepository$1@17b6f1b 更改返回 尺寸。这不受支持。
这就是为什么
// androidx.paging.DataSource
static <A, B> List<B> convert(Function<List<A>, List<B>> function, List<A> source) {
List<B> dest = function.apply(source);
if (dest.size() != source.size()) {
throw new IllegalStateException("Invalid Function " + function
+ " changed return size. This is not supported.");
}
return dest;
}
似乎是分页库的一个限制。有没有办法将PagedList 转换为另一个大小不同的PagedList?
参考链接:
https://issuetracker.google.com/issues/142890117
How to use AAC paging library with list size different than list size returned by Room database
【问题讨论】:
标签: android android-architecture-components android-paging