Android 分页库:如何将一个分页列表转换为另一个大小不同的分页列表?

Android 分页库:如何将一个分页列表转换为另一个大小不同的分页列表?,android,android-architecture-components,android-paging,Android,Android Architecture Components,Android Paging,目前,我们在SQLite房间中存储了一个数据结构,名为Todo 我们目前的工作流程如下 Dao正在返回DataSource.Factory 使用LivePagedListBuilder将DataSource.Factory转换为LiveData 观察LiveData,并使用submitList将PagedList传递到PagedListAdapter 到目前为止,对于这样简单的用例来说是很好的 然而,现在,我们有一个更复杂的UI需求。我们需要将Todo转换为TransformedTodo,然后

目前,我们在SQLite房间中存储了一个数据结构,名为
Todo

我们目前的工作流程如下

  • Dao正在返回
    DataSource.Factory
  • 使用
    LivePagedListBuilder
    DataSource.Factory
    转换为
    LiveData
  • 观察
    LiveData
    ,并使用
    submitList
    PagedList
    传递到
    PagedListAdapter

  • 到目前为止,对于这样简单的用例来说是很好的

    然而,现在,我们有一个更复杂的UI需求。我们需要将
    Todo
    转换为
    TransformedTodo
    ,然后再将
    submitList
    转换为
    PagedListAdapter

    这是我们的变换函数

    List<TransformedTodo> transform(Todo todo)
    
    抛出的异常如下所示

    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;
    }
    
    //androidx.paging.DataSource
    静止的

    TL;DR

    我创建了一个允许分页库的数据源页面变化的页面


    这里的问题是分页库
    mapByPage
    被认为返回的项目数与输入的项目数相同。为了能够返回与输入不同数量的项,需要一个自定义的变异函数

    在继续之前,特别是在使用Room时,另一个需要注意的重要事项是,
    DataSource.Factory
    实际上将生成一个
    PositionalDataSource
    。与
    ItemKeyedDataSource
    PageKeyedDataSource
    不同,它要求生成的页面项遵守定义的页面大小。因此,即使我们创建一个类似于
    mapByPage
    的函数来允许其项的变异,接受不同的返回列表大小,但在使用
    PositionDataSource
    时仍然会导致问题,因为它不允许修改此列表大小

    解决此问题的一个解决方案是将
    位置数据源
    包装在两种静止数据源类型中的另一种类型中,这允许使用非固定页面大小,并使其行为就像它实际上是一个
    位置数据源

    一旦我们有了一个非固定页面大小的兼容“
    positiondatasource
    ”,我们就可以添加类似mapByPage的变异函数

    List<TransformedTodo> transform(Todo todo)
    
    我实际上已经创建了一个简单的库,它正是这样做的。它将
    PositionalDataSource
    包装在一个行为相同的
    PageKeyedDataSource
    中。然后,可以应用
    mutateByPage
    函数,允许更改结果项,甚至更改列表大小或项类型。此外,我还添加了对
    ItemKeyedDataSource
    PageKeyedDataSource
    的变异支持

    请记住,这个库仍然可能包含bug,所以请随时报告任何问题或作出贡献