我有一个名为imageRecyclerView
的水平回收视图,其中每列只包含一个ImageView
。 Recycler视图的适配器类称为ImageAdapter
。 imageRecyclerView
适配器的数据集是包含URL的ArrayList
字符串。 ArrayList
被称为currentImageURLs
。
注意 - 所有这些代码的目的是一次一个地将图像加载到imageRecyclerView
中。
在我的onBindViewHolder
类的ImageAdapter
方法中,我有以下代码。此代码将适配器数据集中的图像加载到ImageView
中。在调用ImageView
将新项添加到适配器的数据集之前,代码也会等待图像加载到recursivelyLoadURLs
中。
Glide.with(context)
//items[[position] is a string that contains a URL
.load(items[position])
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
holder.progressBar.visibility = View.GONE
context.recursivelyLoadURLs()
return false
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
holder.progressBar.visibility = View.GONE
context.recursivelyLoadURLs()
return false
}
})
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC))
.into(holder.imageView)
方法recursivelyLoadURLs
位于父Activity类中。从本质上讲,这种方法的作用是什么
1]添加另一个URL到imageRecyclerView
的适配器的数据集和
2]致电notifyDataSetChanged
所以imageRecyclerView
更新:
fun recursivelyLoadURLs() {
if (currentImageURLs.size >= targetImageURLs.size) {
return
}
currentImageURLs.add(targetImageURLs[currentImageURLs.size])
//The code crashes on this line
mainview.imageRecyclerView.adapter.notifyDataSetChanged()
}
但是,代码在上面的代码示例中标记的行上以java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
异常崩溃。
我怀疑这种情况正在发生,因为imageRecyclerView
在调用notifyDataSetChanged
时仍在计算布局。
如何延迟调用context.recursivelyLoadURLs
直到布局完成计算?
或者,我如何在recursivelyLoadURLs
中添加延迟,以便notifyDataSetChanged
仅在imageRecyclerView
完成计算其新布局后调用?
tompee建议发布一个Runnable,以保证在运行notifyDataSetChanged
之前,回收站视图已经布置了它的子项。
因此,我用notifyDataSetChanged
取代了
mainview.imageRecyclerView.post({
mainview.imageRecyclerView.adapter.notifyDataSetChanged()
})
这解决了这个问题。
您可以阅读RecyclerView.Adapter.notifyDataSetChanged上的文档
此事件未指定数据集的更改内容,强制任何观察者假定所有现有项和结构可能不再有效。 LayoutManagers将被迫完全重新绑定并重新布局所有可见视图。
如果您正在编写适配器,则尽可能使用更具体的更改事件会更有效。依靠notifyDataSetChanged()作为最后的手段。
这里有一些可能有用的提示*希望它有帮助:)
notifyDataSetChanged()
,特别是在你的onBindViewHolder中。请改用notifyItemChanged(position)
。它效率更高,内存成本更低。notifyDataSetChanged()
,请在准备好所有数据后使用它(也许在currentImageURLs.size >= targetImageURLs.size
时使用它)