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

问题描述

我是android kotlin的Paging 3库中的新手。我想要无限的数据。因此,我发现Paging 3库对我的情况很有帮助。我使用了 PagingSource 创建列表。我没有使用Room。我有嵌套 recyclerView。我在Recyclerview中使用 PagingDataAdapter diff util 。我使用了来自 codelab 的推荐的分页库教程,并且成功了,没有任何问题。我面临着难以更新的项目。我使用分页源创建列表,并且列表内部有一些来自服务器的数据。我完全没有任何问题。但是,如何更新适配器或通知数据在reyclerview中已更改。我已经有机制来获取更新的列表。我搜索了如何在某个地方更新适配器,但是提到了每个地方都使用了 DataSource 中的 invalidate() DataSource 用于分页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和字符串数据的项目。我的数据班

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。

谢谢。

解决方法

为了让分页接收新项目,您需要调用PagingSource.invalidate()来通知Pager,它需要获取一个新的PagingSource并重新加载页面。您需要随时跟踪工厂生产的所有PagingSource,并在每次从网络更新后备数据集时使它们无效。

编辑:类似这样的东西,但这是一个非常粗糙的原型

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() }
    }
}