在 Paging 3 库 Android Kotlin 中更新当前页面或更新数据

Posted

技术标签:

【中文标题】在 Paging 3 库 Android Kotlin 中更新当前页面或更新数据【英文标题】:Update Current Page or Update Data in Paging 3 library Android Kotlin 【发布时间】:2021-02-19 06:22:28 【问题描述】:

我是 android kotlin 的 Paging 3 库的新手。我想要无限数据。所以我发现 Paging 3 库对我来说很有帮助。我使用 PagingSource 创建了一个列表。我没有使用房间。我有 nested recyclerView。我将 PagingDataAdapterdiff util 一起用于我的 Recyclerview。我使用了 codelab 推荐的分页库教程,我成功地没有任何问题。我面临更新项目的困难。我使用分页源创建列表,在列表内部我有一些来自服务器的数据。我完全没有任何问题。但是在 reyclerview 中如何更新适配器或通知数据已经改变。我已经有机制来获取更新的列表。我搜索了如何在某个地方更新适配器,但每个地方都提到使用 DataSource 中的 invalidate()DataSource 用于 paging 2 对吧?现在,根据Migrate to Paging 3 中的文档,这在分页 3 中。我使用 Flow 来检索数据。此代码在 viewmodel 类中。

fun createRepo(data: List<String>, repository: RepositoryData): Flow<PagingData<UnlimitData>> 
    return repository.getStreamData(data).cachedIn(viewModelScope)

我正在传递来自服务器的列表。 getStreamData 函数返回带有 int 和 string 数据的项目。我的数据类

data class UnlimitData(val id: Int, val name: String)

createRepo 正在调用我的活动类以在 adpater 中发送数据。

lifecycleScope.launch 
        viewModel.createRepo(serverData,repository).collectLatest  data ->
            adapter.submitData(data)
        

这是我的适配器代码:-

class unlimitedAdapter() :
    PagingDataAdapter<UnlimitData, RecyclerView.ViewHolder>(COMPARATOR) 

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
    val item = getItem(position)
    if (item != null) 
        (holder as UnlimitedViewHolder).bind(item)
    


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder 
    return UnlimitedViewHolder.create(parent)


companion object 
    private val COMPARATOR = object : DiffUtil.ItemCallback<UnlimitData>() 
        override fun areItemsTheSame(oldItem: UnlimitData, newItem: UnlimitData): Boolean =
            oldItem.id == newItem.id

        override fun areContentsTheSame(oldItem: UnlimitData, newItem: UnlimitData): Boolean = oldItem == newItem
    

我使用 RetroFit 添加了在列表中插入/更新数据的逻辑。我的列表已成功更新,但无法刷新 reyclerview。

提前致谢。

【问题讨论】:

【参考方案1】:

为了分页获取新项目,您需要致电PagingSource.invalidate() 通知Pager 它需要获取新的PagingSource 并重新加载页面。您需要跟踪工厂生产的所有PagingSources,并在您从网络更新支持数据集时使它们失效。

编辑:像这样,但这是一个非常粗糙的原型

abstract class InvalidatingPagingSourceFactory<K,V> : () -> PagingSource<K,V> 
    private val list = mutableListOf()

    abstract fun create()

    override final fun invoke() 
        create().also  list.add(it) 
    

    fun invalidate() 
        while (list.isNotEmpty())  list.removeFirst().invalidate() 
    

【讨论】:

嗨@dlam 感谢您的回复。您能否详细解释一下如何跟踪所有 PagingSource。我是分页库的新手。谢谢 在您传递给PagerPagingSourceFactory 中,您需要一些东西来保存您创建的PagingSources 的引用列表,并有某种回调告诉您何时您的支持数据集更改并无效 + 清除该列表。此错误中的一些示例代码可能会帮助您入门:issuetracker.google.com/160716447 嗨@dlam 感谢您的回复。我可以得到更清晰的工作示例吗? 你点击了链接吗? 有什么我可以帮助扩展的具体内容吗?您基本上需要调用.invalidate()(这也是一个分页源API)来让分页使用您提供的工厂创建一个新的PagingSource 来重新加载数据。您尝试了哪些方法,哪些方法无效?

以上是关于在 Paging 3 库 Android Kotlin 中更新当前页面或更新数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jetpack Compose 无限加载 Android Paging 3 库而无需滚动

Android Paging 库不会触发 loadAfter()

Android Paging 3 - 从 PagingData<T> 对象获取数据列表

如何检查 Paging 3 库中的列表大小或空列表

如何使用 Paging 3 库更新单个项目

将 Paging 3 alpha 更新为稳定导致索引问题 Android