如何实现List<Object>与PagedList<Object>的双向转换?
如何实现List与Android Paging库的PagedList双向转换?
嘿,刚好我之前在项目里处理过类似的转换需求,这两个场景的具体实现方法我给你拆解清楚:
1. 将List<String>转换为PagedList<String>
PagedList本身依赖于数据源(DataSource)来提供分页数据,所以我们需要先创建一个基于现有List的静态数据源,再通过LivePagedListBuilder来构建PagedList。这里用PositionalDataSource最合适,因为我们的数据源是固定长度的列表:
步骤1:实现自定义静态数据源
class StaticStringDataSource(private val dataList: List<String>) : PositionalDataSource<String>() { override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<String>) { val totalCount = dataList.size // 计算初始加载的起始位置和数量 val startPosition = computeInitialLoadPosition(params, totalCount) val loadSize = computeInitialLoadSize(params, startPosition, totalCount) // 返回对应区间的数据 callback.onResult(dataList.subList(startPosition, startPosition + loadSize), startPosition, totalCount) } override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<String>) { // 返回指定区间的数据 callback.onResult(dataList.subList(params.startPosition, params.startPosition + params.loadSize)) } }
步骤2:构建PagedList
通过DataSource.Factory包装我们的自定义数据源,再配合PagedList.Config配置分页参数,最后生成LiveData包装的PagedList(推荐用LiveData来管理生命周期):
fun convertListToPagedList(strList: List<String>): LiveData<PagedList<String>> { // 配置分页参数,按需调整 val pagedConfig = PagedList.Config.Builder() .setPageSize(20) // 每页加载的数量 .setEnablePlaceholders(true) // 是否启用占位符(显示空位置) .setPrefetchDistance(10) // 提前加载的距离(距离底部还有10条时加载下一页) .build() // 创建数据源工厂 val dataSourceFactory = object : DataSource.Factory<Int, String>() { override fun create(): DataSource<Int, String> { return StaticStringDataSource(strList) } } // 构建并返回LiveData<PagedList> return LivePagedListBuilder(dataSourceFactory, pagedConfig).build() }
注意:如果你需要直接获取PagedList实例,可以通过观察这个LiveData来获取,比如在Activity/Fragment中用observe方法监听。
2. 将PagedList<Object>转换为List<Object>
这个就简单多了!因为PagedList本身实现了Iterable接口,我们可以直接遍历收集元素,或者用语言自带的快捷方法:
Kotlin 实现
fun convertPagedListToList(pagedList: PagedList<Object>): List<Object> { return pagedList.toList() }
Java 实现
public List<Object> convertPagedListToList(PagedList<Object> pagedList) { List<Object> resultList = new ArrayList<>(); for (Object item : pagedList) { resultList.add(item); } return resultList; }
重要提醒:PagedList是分页加载的,如果你调用转换方法时,PagedList还没加载完所有数据,得到的List只会包含当前已经加载的部分。如果需要获取全部数据,你可以通过PagedList.addWeakCallback()监听加载状态,等所有数据加载完成后再执行转换:
pagedList.addWeakCallback(null, object : PagedList.Callback() { override fun onChanged(position: Int, count: Int) {} override fun onInserted(position: Int, count: Int) {} override fun onRemoved(position: Int, count: Int) {} })
或者检查pagedList.loadState(Paging 3+)来判断是否全部加载完成。
内容的提问来源于stack exchange,提问作者Santanu Sur
相关产品推荐
相关产品推荐

