我有一个名为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]为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
计算完新布局后调用?
答案 0 :(得分:1)
tompee建议发布一个Runnable,以确保回收者视图在运行notifyDataSetChanged
之前已经布置了其子项。
因此,我将notifyDataSetChanged
替换为
mainview.imageRecyclerView.post({
mainview.imageRecyclerView.adapter.notifyDataSetChanged()
})
这解决了这个问题。
答案 1 :(得分:0)
您可以阅读RecyclerView.Adapter.notifyDataSetChanged
上的文档此事件未指定数据集的更改内容,强制任何观察者假定所有现有项目和结构可能不再有效。 LayoutManagers将被迫完全重新绑定并重新布局所有可见视图。
如果您正在编写适配器,则尽可能使用更具体的更改事件会更有效。依靠notifyDataSetChanged()作为最后的手段。
以下是一些可能有用的提示*希望它有所帮助:)
notifyDataSetChanged()
,尤其是在onBindViewHolder中。请改用notifyItemChanged(position)
。它效率更高,内存成本更低。notifyDataSetChanged()
,请在准备好所有数据后使用它(可能在currentImageURLs.size >= targetImageURLs.size
时使用)