NotifyDataSetChanged 没有正确更新 RecyclerView
NotifyDataSetChanged does not update the RecyclerView correctly
我试图在我的 recyclerview 适配器中实现一个相当基本的逻辑,但是 notifyDataSetChanged()
让我很头疼。
我有一个如下所示的过滤方法:
fun filter(category: Int) {
Thread(Runnable {
activeFiltered!!.clear()
if (category == -1) {
filterAll()
} else {
filterCategory(category)
}
(mContext as Activity).runOnUiThread {
notifyDataSetChanged()
}
}).start()
}
其中 filterAll()
和 filterCategory()
函数非常简单:
private fun filterAll() {
activeFiltered?.addAll(tempList!!)
}
private fun filterCategory(category: Int) {
for (sub in tempList!!) {
if (sub.category == category) {
activeFiltered?.add(sub)
}
}
}
当我 运行 此代码并按类别过滤列表时,activeFiltered 列表已正确更新并包含我期望的项目,但是当 notifyDataSetChanged()
为 运行 时,它只会削减列表的范围而不更新项目。
有办法解决这个问题吗?
我也试过,而不是 notifyDataSetChanged() 使用:
activeFiltered!!.forEachIndexed {index, _ -> notifyItemChanged(index)}
但问题依然存在
这也不是线程问题,因为我尝试将整个逻辑放在主线程中,但列表仍然没有正确更新。
这是我的 onBindViewHolder()
:
override fun onBindViewHolder(viewHolder: ActiveViewHolder, pos: Int) {
sub = activeFiltered!![pos]
inflateView()
}
这是我夸大我的文本的地方,sub是onBindViewHolder()
中设置的实例变量:
private fun inflateView() {
viewHolder.title.text = sub.title
}
我认为您使用的是 onBindView()
中的原始数组,而不是过滤后的数组。
onBindViewHolder()
的执行似乎不正确。为了更新列表项,应使用传入的 viewHolder
参数(而不是您在 onCreateViewHolder()
中创建的 viewHolder
)。
正确的实现应该是这样的
override fun onBindViewHolder(viewHolder: ActiveViewHolder, pos: Int) {
val sub = activeFiltered!![pos]
inflateView(viewHolder, sub)
}
private fun inflateView(viewHolder: ActiveViewHolder, sub: <YourDataType>) {
viewHolder.title.text = sub.title
}
顺便说一句,将某些内容保存为成员字段以便通过多种方法访问它并不是一个好习惯。随意将其作为参数传递给此类方法。在上面的代码中,我将 sub
作为参数传递,而不是将其存储为成员。
而且也没有必要保留您在 onCreateViewHolder()
中创建的 viewHolder
。我们主要在某些回调方法(如 onBindViewHolder()
等)中需要它们,这些方法将接收正确的 viewHolder
作为参数。
我试图在我的 recyclerview 适配器中实现一个相当基本的逻辑,但是 notifyDataSetChanged()
让我很头疼。
我有一个如下所示的过滤方法:
fun filter(category: Int) {
Thread(Runnable {
activeFiltered!!.clear()
if (category == -1) {
filterAll()
} else {
filterCategory(category)
}
(mContext as Activity).runOnUiThread {
notifyDataSetChanged()
}
}).start()
}
其中 filterAll()
和 filterCategory()
函数非常简单:
private fun filterAll() {
activeFiltered?.addAll(tempList!!)
}
private fun filterCategory(category: Int) {
for (sub in tempList!!) {
if (sub.category == category) {
activeFiltered?.add(sub)
}
}
}
当我 运行 此代码并按类别过滤列表时,activeFiltered 列表已正确更新并包含我期望的项目,但是当 notifyDataSetChanged()
为 运行 时,它只会削减列表的范围而不更新项目。
有办法解决这个问题吗?
我也试过,而不是 notifyDataSetChanged() 使用:
activeFiltered!!.forEachIndexed {index, _ -> notifyItemChanged(index)}
但问题依然存在
这也不是线程问题,因为我尝试将整个逻辑放在主线程中,但列表仍然没有正确更新。
这是我的 onBindViewHolder()
:
override fun onBindViewHolder(viewHolder: ActiveViewHolder, pos: Int) {
sub = activeFiltered!![pos]
inflateView()
}
这是我夸大我的文本的地方,sub是onBindViewHolder()
中设置的实例变量:
private fun inflateView() {
viewHolder.title.text = sub.title
}
我认为您使用的是 onBindView()
中的原始数组,而不是过滤后的数组。
onBindViewHolder()
的执行似乎不正确。为了更新列表项,应使用传入的 viewHolder
参数(而不是您在 onCreateViewHolder()
中创建的 viewHolder
)。
正确的实现应该是这样的
override fun onBindViewHolder(viewHolder: ActiveViewHolder, pos: Int) {
val sub = activeFiltered!![pos]
inflateView(viewHolder, sub)
}
private fun inflateView(viewHolder: ActiveViewHolder, sub: <YourDataType>) {
viewHolder.title.text = sub.title
}
顺便说一句,将某些内容保存为成员字段以便通过多种方法访问它并不是一个好习惯。随意将其作为参数传递给此类方法。在上面的代码中,我将 sub
作为参数传递,而不是将其存储为成员。
而且也没有必要保留您在 onCreateViewHolder()
中创建的 viewHolder
。我们主要在某些回调方法(如 onBindViewHolder()
等)中需要它们,这些方法将接收正确的 viewHolder
作为参数。