[英]How to update the data passed to the adapter without recreating it android kotlin
Faced such a problem: I have a RecyclerView
, the data for which I get from the ViewModel
using StateFlow
:面临这样的问题:我有一个
RecyclerView
,我使用StateFlow
从ViewModel
获取的数据:
viewModel.items.collect {
setRecyclerView(items)
}
Then, let's say, somewhere inside the Fragment
, I change the data for items and there are more of them.然后,比方说,在
Fragment
内部的某处,我更改了项目的数据并且有更多的项目。 In order for my RecyclerView
to see my changes, I have to call the setRecyclerView(items)
function again, which, it seems to me, can lead to the most unexpected consequences (for example, items will be duplicated).为了让我的
RecyclerView
看到我的更改,我必须再次调用setRecyclerView(items)
function,在我看来,这可能会导致最意想不到的后果(例如,项目将被复制)。 The question is: is it possible to somehow change the data and update the RecyclerView
(including the onBindViewHolder
function in it) without yet another creation of an Adapter
?问题是:是否有可能以某种方式更改数据并更新
RecyclerView
(包括其中的onBindViewHolder
function)而无需再次创建Adapter
?
Let's start talking about the adapter implementation.让我们开始讨论适配器实现。 Reading your question, I believe you used RecyclerView.Adapter to implement your adapter.
阅读您的问题,我相信您使用 RecyclerView.Adapter 来实现您的适配器。 But there is another option that is simpler and more performant than this.
但还有另一种选择比这更简单、性能更高。 It's the ListAdapter:
这是 ListAdapter:
The most interesting thing about ListAdapter is the DiffUtil, that have a performative way to check if any item on your list was updated, deleted, or included. ListAdapter 最有趣的地方是 DiffUtil,它有一种有效的方法来检查列表中的任何项目是否已更新、删除或包含。 Here's a sample of the implementation:
以下是实施示例:
abstract class MyAdapter: ListAdapter<ItemModel, MyAdapter.MyViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val binding = ItemSimplePosterBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return MyViewHolder(binding)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(getItem(position))
}
class MyViewHolder(
private val binding: ItemSimplePosterBinding
): RecyclerView.ViewHolder(binding.root) {
fun bind(item: ItemModel) {
// Here you can get the item values to put these values on your view
}
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<ItemModel>() {
override fun areItemsTheSame(oldItem: ItemModel, newItem: ItemModel): Boolean {
// need a unique identifier to have sure they are the same item. could be a comparison of ids. In this case, that is just a list of strings just compares like this below
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: ItemModel, newItem: ItemModel): Boolean {
// compare the objects
return oldItem == newItem
}
}
}
}
So, when your list is updated, you just have to call the submitList from the adapter, like this:因此,当您的列表更新时,您只需从适配器调用 submitList,如下所示:
viewModel.items.collectLatest { items ->
// You will send the items to your adapter here
adapter.submitList(items)
}
Then, your RecyclerView just has to be configured on onViewCreated for example, and your list can be defined and updated in another place, observing the items change from ViewModel.然后,您的 RecyclerView 只需在 onViewCreated 上配置,例如,您的列表可以在另一个地方定义和更新,观察 ViewModel 中的项目变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.