gpt4 book ai didi

android - viewHolder 类中的 notifyDataSetChanged

转载 作者:行者123 更新时间:2023-12-02 13:05:34 25 4
gpt4 key购买 nike

我可以在 View Holder 中使用 notifyDataSetChanged() 吗?

class ItemViewHolder(context: Context?, view: View) : RecyclerView.ViewHolder(view) {

func update(){
// ...
// i need to update adapter for example
adapter.notifyDataSetChanged()
}

}

最佳答案

转动你的 class进入 inner class当然是一种方法。我也会考虑把你的 ViewHolder 交给我对 Listener 的引用或 Callback您提出的界面(或一组功能)也是如此。如果您决定将 ViewHolder 移动到不同的文件或适配器之外,这将使重构更容易。它还更好地遵守了单一职责原则,因为我们从 ViewHolder 中删除了数据管理,并让它在其他地方发生。

例如:

class ViewHolder(
private itemView: View
private val onDataSetChanged: () -> Unit
) : RecyclerView.ViewHolder(itemView) {

fun onUpdate() {
// Perform changes...
onDataSetChanged()
}

}

虽然 ViewHolder 会像这样操纵数据项,但我觉得有点奇怪。通常,这些只保存项目的位置信息和 View 状态,而不是项目本身。另一种方法可能是将位置信息传递给更新 lambda:

class ViewHolder(
private itemView: View
private val onDataSetChanged: (Int) -> Unit
) : RecyclerView.ViewHolder(itemView) {

fun onShouldUpdate() {
if (adapterPosition == RecyclerView.NO_POSITION) return
onDataSetChanged(adapterPosition)
}

}

然后在别处处理该更新。例如,在 Adapter 或 ViewModel 逻辑中:

fun onCreateViewHolder(...) {
val viewHolder = ViewHolder(...) { /* do update */ }
}

这使我们处于现在适配器负责将数据映射到 View 以及管理数据状态的地步……这不是很干净。

这是我喜欢的做法:

class Adapter(private val updateItem: (Item) -> Unit) {
fun onCreateViewHolder(...) {
return ViewHolder(...) { updateItem(items[it]) }
}
}

我们在更合理的地方处理数据操作。这里:

  1. ViewHolder 将点击或更新事件映射到它持有的项目的位置
  2. 适配器将位置映射到实际数据项
  3. Presentation 对象(例如 Architecture Components ViewModel)(向适配器提供 lambda 的任何人)执行操作。 (更多内容见下文)

在这种情况下,您的 notifyDataSetChanged 将由演示者处理,然后反馈给适配器。例如,您在 Adapter 上有一个名为 setData(items: List<Item>) 的方法。 .当新的项目列表可用时,演示者通知适配器,适配器设置项目:

// In your adapter
fun setData(newItems: List<Item>) {
val oldItems = items
items = newItems
notifyDataSetChanged()
// Alternatively, utilize DiffUtil
}

您的 ViewModel 然后可以公开一个可观察的字段,也许利用 LiveData .

class MyViewModel : ViewModel() {
val items: LiveData<List<Item>>
fun updateItem(item: Item) { ... }
}

您的 Activity,即您设置适配器的地方,然后可以观察到对此的更改:

val adapter = Adapter(viewModel::updateItem)

// Note you could probably use a method reference instead of a lambda.
viewModel.items.observe(this) { adapter.setItems(it) }

我希望这有助于概述该方法。我可以整天谈论这个,所以请随时提出任何问题。这里的想法是,我们清楚地分离了我们的关注点 (SRP),消除了将整个适配器交给 ViewHolder (ISP) 的需要,并利用 lambda 来确保我们不直接依赖于我们不需要的东西成为(DIP)。

关于android - viewHolder 类中的 notifyDataSetChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57056380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com