[英]NotifyDataSetChanged does not update the RecyclerView correctly
I am trying to implement a fairly basic logic within my recyclerview adapter but notifyDataSetChanged()
is giving me quite the headache. 我正在尝试在我的recyclerview适配器中实现一个相当基本的逻辑,但是
notifyDataSetChanged()
给我带来了很大的麻烦。
I have a filter method that looks like this: 我有一个看起来像这样的过滤器方法:
fun filter(category: Int) {
Thread(Runnable {
activeFiltered!!.clear()
if (category == -1) {
filterAll()
} else {
filterCategory(category)
}
(mContext as Activity).runOnUiThread {
notifyDataSetChanged()
}
}).start()
}
where filterAll()
and filterCategory()
functions are quite easy: filterAll()
和filterCategory()
函数非常简单:
private fun filterAll() {
activeFiltered?.addAll(tempList!!)
}
private fun filterCategory(category: Int) {
for (sub in tempList!!) {
if (sub.category == category) {
activeFiltered?.add(sub)
}
}
}
When I run this code and filter the list by category the activeFiltered list is updated correctly and contains the items I expect, but when notifyDataSetChanged()
is run it only cuts the list's range without updating the items. 当我运行此代码并按类别过滤列表时,activeFiltered列表会正确更新并包含我期望的项目,但是当
notifyDataSetChanged()
运行时,它只会切出列表的范围而不更新项目。
Is there a way to fix this? 有没有办法解决这个问题?
I also tried, instead of notifyDataSetChanged() to use: 我也尝试过,而不是使用notifyDataSetChanged():
activeFiltered!!.forEachIndexed {index, _ -> notifyItemChanged(index)}
but the problem is still there. 但是问题仍然存在。
It isn't a threading issue either since I tried putting the whole logic in the main thread and the list still wasn't updated correctly. 这也不是线程问题,因为我尝试将整个逻辑放入主线程,并且列表仍未正确更新。
This is my onBindViewHolder()
: 这是我的
onBindViewHolder()
:
override fun onBindViewHolder(viewHolder: ActiveViewHolder, pos: Int) {
sub = activeFiltered!![pos]
inflateView()
}
This is where I inflate my text, sub is the instance variable set in the onBindViewHolder()
: 这是我在
onBindViewHolder()
文本的地方,sub是在onBindViewHolder()
设置的实例变量:
private fun inflateView() {
viewHolder.title.text = sub.title
}
It seems the implementation of onBindViewHolder()
is incorrect. 似乎
onBindViewHolder()
的实现不正确。 In order to update a list item, the passed in viewHolder
parameter should be used (not the viewHolder
you created in the onCreateViewHolder()
). 为了更新列表项,应该使用传入的
viewHolder
参数(而不是您在onCreateViewHolder()
创建的viewHolder
)。
The correct implementation should be like 正确的实现应该像
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
}
By the way, it is not a good practice to hold something as a member field in order to access it in several methods. 顺便说一句,将某些内容保留为成员字段以几种方法访问它不是一个好习惯。 Feel free to pass it as arguments to such methods.
随时将其作为此类方法的参数传递。 In the above code I passed the
sub
as argument and not stored it as a member. 在上面的代码中,我将
sub
作为参数传递,而不是将其存储为成员。
And also it is not necessary to hold the viewHolder
that you create in onCreateViewHolder()
. 而且也不必保留在
onCreateViewHolder()
创建的viewHolder
。 We mostly need them in some callback methods (like onBindViewHolder()
, etc) and these methods will receive the right viewHolder
as arguments. 我们通常在某些回调方法(例如
onBindViewHolder()
等)中需要它们,并且这些方法将接收正确的viewHolder
作为参数。
我认为您是在onBindView()
中使用原始数组,而不是经过过滤的数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.