0

我正在寻找一种方法来PagingDataAdapter从 Paging 3 库中更新我的特定项目。目前推荐的方法似乎是使 无效,PagingSource但这会导致适配器再次获取整个数据集,这效率不高,并且还显示了我的加载微调器。

但是,我注意到我可以使用该peek()方法访问和修改适配器中的项目,并且它似乎工作得很好。我在这里错过了什么吗?这会在某些情况下分崩离析吗?我知道保持数据类不可变是一种很好的做法,但这种方法让我的生活更轻松。这是我的用法示例,它似乎工作得很好:

viewModel.chatMessageUpdateEvents.collect { messageEvent ->
    when (messageEvent) {
        is FirestoreChatMessageListener.ChatMessageUpdateEvent.MessageUpdate -> {
            val update = messageEvent.chatMessage
            val historyAdapterItems = chatMessagesHistoryAdapter.snapshot().items
            val updatedMessage =
                historyAdapterItems.find { chatMessage ->
                    chatMessage.documentId == messageEvent.chatMessage.documentId
                }
            if (updatedMessage != null) {
                val messagePosition = historyAdapterItems.indexOf(updatedMessage)
                chatMessagesHistoryAdapter.peek(messagePosition)?.unsent = update.unsent
                chatMessagesHistoryAdapter.peek(messagePosition)?.imageUrl = update.imageUrl
                chatMessagesHistoryAdapter.notifyItemChanged(messagePosition)
            }
        }
    }
}
4

1 回答 1

1

我在单独的评论中回复,但想在这里发帖以提高知名度。

确实不建议这样做,并且完全不支持分页的使用。

Pager().flow()如果尚未清理(例如,如果 ViewModel 尚未清理) ,则恢复状态的主要方法之一是通过该.cachedIn(scope)方法,该方法将在您的情况下缓存过时的数据。这也是多播(使 PagingData 中加载的数据可重用)以用于流操作的唯一方法,例如.combine()允许您将转换与外部信号混合。

您还需要处理飞行中加载之间的竞争,如果在追加完成的同时收到 messageEvent 会发生什么?在这种情况下谁赢了,是否有可能在.snapshot()插入新页面之间以使您的通知位置不再正确?

一般来说,拥有单一事实来源要简单得多,这是推荐的路径,因此建议始终是在每次支持数据集更新时都无效。

Paging 的问题跟踪器中有一个开放的 FR 来支持Flow<Item>Flow<Page>设置数据样式以允许粒度更新,但这肯定是一个更远的未来:https ://issuetracker.google.com/160232968

于 2021-01-12T19:46:35.500 回答