How to convert a List<Object> to PagedList<Object> and vice-versa?

后端 未结 3 1020
梦谈多话
梦谈多话 2021-02-12 07:08

PagedList is used for Android\'s cool paging library. To make the question as minimal as possible : If i have a list of strings like

          


        
      
      
      
3条回答
  •  悲&欢浪女
    2021-02-12 07:51

    I'll start with the easier part, if you want to converter a PagedList<> to a a List<> you can use the snapshot() method, as you can seen in the docs it retuns:

    Returns an immutable snapshot of the PagedList in its current state.A PagedList snapshot is simply an immutable shallow copy of the current state of the PagedList as a List.

    Now as for the other way around you'll need to use PagedList.Builder and for that you'd need a DataSource to create the PagedList. So a avery basic dataSource that would manage your static list would look like this:

    StringDataSource.kt

    class StringDataSource(val provider: StringListProvider) : PageKeyedDataSource() {
        override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback) {
            val list = provider.getStringList(0, params.requestedLoadSize)
            callback.onResult(list, 1, 2)
        }
    
        override fun loadAfter(params: LoadParams, callback: LoadCallback) {
            val list = provider.getStringList(params.key, params.requestedLoadSize)
            callback.onResult(list, params.key + 1)
        }
    
        override fun loadBefore(params: LoadParams, callback: LoadCallback) {
            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
        }
    }
    

    As you can see you need to override the three methods loadInitial, loadAfter and loadBefore in order to tell the datasource how to load the cunks of data from the list. I've wrapped you list in a provider class just for organization purposes.

    StringListProvider.kt

    class StringListProvider(val list: List) {
    
    
        fun getStringList(page: Int, pageSize: Int): List {
    
            val initialIndex = page * pageSize
            val finalIndex = initialIndex + pageSize
            //TODO manage index out of range
            return list.subList(initialIndex, finalIndex)
        }
    }
    

    To use the data source to generate the PagedList you need to build a simple configuration with PagedList.Config.Builder:

        val myConfig = PagedList.Config.Builder()
                .setInitialLoadSizeHint(PAGE_SIZE)
                .setPageSize(PAGE_SIZE)
                .build()
    

    And then pass that to the PagedList.Builder with the datasource:

        val pagedStrings: PagedList = PagedList.Builder(StringDataSource(StringListProvider(originalStrings)), myConfig)
                .setInitialKey(0)
                .build()
    

    Now you have a PagedList in pagedStrings.

    The same thing in java:

    StringListProvider.java

    public class StringListProvider {
    
        private List list;
    
        public StringListProvider(List list) {
            this.list = list;
        }
    
        public List getStringList(int page, int pageSize) {
            int initialIndex = page * pageSize;
            int finalIndex = initialIndex + pageSize;
    
            //TODO manage out of range index
    
            return list.subList(initialIndex, finalIndex);
        }
    }
    

    StringDataSource.java

    public class StringDataSource extends PageKeyedDataSource {
    
        public static final int PAGE_SIZE = 20;
        private StringListProvider provider;
    
        public StringDataSource(StringListProvider provider) {
            this.provider = provider;
        }
    
        @Override
        public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) {
            List result = provider.getStringList(0, params.requestedLoadSize);
            callback.onResult(result, 1, 2);
        }
    
        @Override
        public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) {
            List 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 params, @NonNull LoadCallback callback) {
            List result = provider.getStringList(params.key, params.requestedLoadSize);
            callback.onResult(result, params.key + 1);
        }
    }
    

    Config generation

        PagedList.Config myConfig = new PagedList.Config.Builder()
                .setInitialLoadSizeHint(PAGE_SIZE)
                .setPageSize(PAGE_SIZE)
                .build();
    

    List convertion

        List myList = new ArrayList<>();
        StringListProvider provider = new StringListProvider(myList);
        StringDataSource dataSource = new StringDataSource(provider);
        PagedList pagedStrings = new PagedList.Builder(dataSource, myConfig)
                .setInitialKey(0)
                .build();
    

提交回复
热议问题