如何将List <Object>转换为PagedList <Object>,反之亦然?

San*_*Sur 15 android rx-java2 android-livedata android-architecture-components android-jetpack

PagedList<Object>用于Android的酷分页库.要使问题尽可能小:如果我有一个字符串列表,如

  List<String> stringList; // it consists of 200 strings
Run Code Online (Sandbox Code Playgroud)

我想转换 stringList为PagedList<String>类似的类型

  PagedList<String> pagedStringList;
Run Code Online (Sandbox Code Playgroud)

而且,如果我有一个PagedList<Object>如何将其转换为List<Object>?我经历了这个以供参考

如果我尝试相反的方式....

我怎么能转换List<Object>成DataSource.Factory<Integer, Object>..所以间接我可以把它转换成PagedList<>?

从DataSource.Factory<Integer, Object>我可以转换为PagedList<>但我怎么能转换list成PagedList<>?

Lev*_*ira 7

我将从较简单的部分开始,如果您想将PagedList <>转换为List <>,则可以使用该snapshot()方法,如它在重新调整的文档中所示:

返回当前状态的PagedList的不变快照。PagedList快照只是PagedList的当前状态作为列表的不变不变的浅表副本。

现在,关于另一种方法,您将需要使用PagedList.Builder,为此,您需要一个数据源来创建PagedList。因此,用于管理您的静态列表的每个基本数据源都将如下所示:

StringDataSource.kt

class StringDataSource(val provider: StringListProvider) : PageKeyedDataSource<Int, String>() {
    override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, String>) {
        val list = provider.getStringList(0, params.requestedLoadSize)
        callback.onResult(list, 1, 2)
    }

    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, String>) {
        val list = provider.getStringList(params.key, params.requestedLoadSize)
        callback.onResult(list, params.key + 1)
    }

    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, String>) {
        val list = provider.getStringList(params.key, params.requestedLoadSize)
        val nextIndex = if (params.key > 1) params.key - 1 else null
        callback.onResult(list, nextIndex)
    }

    companion object {
        const val PAGE_SIZE = 20
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,您需要重写这三种方法loadInitial,loadAfter并loadBefore告诉数据源如何从列表中加载数据块。我已经将您的列表包装在提供程序类中,仅用于组织目的。

StringListProvider.kt

class StringListProvider(val list: List<String>) {


    fun getStringList(page: Int, pageSize: Int): List<String> {

        val initialIndex = page * pageSize
        val finalIndex = initialIndex + pageSize
        //TODO manage index out of range
        return list.subList(initialIndex, finalIndex)
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用数据源生成PagedList,您需要使用以下命令构建一个简单的配置PagedList.Config.Builder:

    val myConfig = PagedList.Config.Builder()
            .setInitialLoadSizeHint(PAGE_SIZE)
            .setPageSize(PAGE_SIZE)
            .build()
Run Code Online (Sandbox Code Playgroud)

然后将其传递给PagedList.Builder数据源:

    val pagedStrings: PagedList<String> = PagedList.Builder<Int, String>(StringDataSource(StringListProvider(originalStrings)), myConfig)
            .setInitialKey(0)
            .build()
Run Code Online (Sandbox Code Playgroud)

现在,您在中有一个PagedList pagedStrings。

Java中的相同之处:

StringListProvider.java

public class StringListProvider {

    private List<String> list;

    public StringListProvider(List<String> list) {
        this.list = list;
    }

    public List<String> getStringList(int page, int pageSize) {
        int initialIndex = page * pageSize;
        int finalIndex = initialIndex + pageSize;

        //TODO manage out of range index

        return list.subList(initialIndex, finalIndex);
    }
}
Run Code Online (Sandbox Code Playgroud)

StringDataSource.java

public class StringDataSource extends PageKeyedDataSource<Integer, String> {

    public static final int PAGE_SIZE = 20;
    private StringListProvider provider;

    public StringDataSource(StringListProvider provider) {
        this.provider = provider;
    }

    @Override
    public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, String> callback) {
        List<String> result = provider.getStringList(0, params.requestedLoadSize);
        callback.onResult(result, 1, 2);
    }

    @Override
    public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, String> callback) {
        List<String> result = provider.getStringList(params.key, params.requestedLoadSize);
        Integer nextIndex = null;

        if (params.key > 1) {
            nextIndex = params.key - 1;
        }
        callback.onResult(result, nextIndex);
    }

    @Override
    public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, String> callback) {
        List<String> result = provider.getStringList(params.key, params.requestedLoadSize);
        callback.onResult(result, params.key + 1);
    }
}
Run Code Online (Sandbox Code Playgroud)

配置生成

    PagedList.Config myConfig = new PagedList.Config.Builder()
            .setInitialLoadSizeHint(PAGE_SIZE)
            .setPageSize(PAGE_SIZE)
            .build();
Run Code Online (Sandbox Code Playgroud)

列表转换

    List<String> myList = new ArrayList<>();
    StringListProvider provider = new StringListProvider(myList);
    StringDataSource dataSource = new StringDataSource(provider);
    PagedList<String> pagedStrings = new PagedList.Builder<Integer, String>(dataSource, myConfig)
            .setInitialKey(0)
            .build();
Run Code Online (Sandbox Code Playgroud)

  • 当您建立PagedList对象时,您需要设置`setNotifyExecutor`和`setFetchExecutor`方法,否则会崩溃 (4认同)