在适配器内交换元素
我正在制作FTP中的文件Explorer同步目录,我希望在下载新项目时首先在RecyClerview中显示。为此,我使用共享流程存储新文件,因此我在其旁边或不显示一个点以通知其是新的。然后,我想将其放在我的mutablelist的开始时,一切顺利,除非我必须使用notifyEtemmeved()更新,这给了我以下错误:
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{e8a722f VFED..... ......ID 0,60-1536,1098 #7f080104 app:id/main_folder_recycle_view}, adapter:fr.frd.calvezdocs.adapter.DirAdapter@f17203c, layout:androidx.recyclerview.widget.GridLayoutManager@31331c5, context:fr.frd.calvezdocs.MainActivity@5181ba0
这是我的onbindviewholder()中的代码():
val isRead: String? = prefNewDir.getString(currentDir.absolutePath, null)
if (isRead!=null) {
holder.DirIsRead.visibility = View.VISIBLE
println("before : " + items[0])
items.remove(currentDir)
items.add(0,currentDir)
println("after : "+items[0])
// Can't update the recyclerview
notifyDataSetChanged()
} else
holder.DirIsRead.visibility = View.GONE
有人有想法吗?
谢谢
I'm making a file explorer synchronizing a directory in ftp, I would like that when a new item is downloaded it is displayed first in my recyclerview. For that I use sharedpreferences to store the new files and so I display or not a dot next to it to notify that it is new. Then I want to place it first at the begining of my MutableList, everything goes well except when I have to update with notifyItemMoved() which gives me the following error:
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{e8a722f VFED..... ......ID 0,60-1536,1098 #7f080104 app:id/main_folder_recycle_view}, adapter:fr.frd.calvezdocs.adapter.DirAdapter@f17203c, layout:androidx.recyclerview.widget.GridLayoutManager@31331c5, context:fr.frd.calvezdocs.MainActivity@5181ba0
Here is the code in my onBindViewHolder() :
val isRead: String? = prefNewDir.getString(currentDir.absolutePath, null)
if (isRead!=null) {
holder.DirIsRead.visibility = View.VISIBLE
println("before : " + items[0])
items.remove(currentDir)
items.add(0,currentDir)
println("after : "+items[0])
// Can't update the recyclerview
notifyDataSetChanged()
} else
holder.DirIsRead.visibility = View.GONE
Does anyone have an idea?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
OnBindViewHolder
是适配器显示列表时调用的方法,并且它通过您的view> Viewholder
,因此您可以更新它以在列表中显示特定项目。这不是做一些事情之类的地方,例如计算列表已更改并请求新布局,这就是为什么您会得到异常的原因。当
recyClerview
试图显示部分时,您也绝对不应该更改项目
数据集!实际上,您的适配器应该具有某种
setData
函数,您可以在其中传递更新的数据,并且可以做一些事情,例如处理移动的内容,对显示列表进行排序,保留列表的列表需要一个突出显示的点等。并且该功能可以调用notifyDataSetchanged()
,或者是更具体的(更好)更新功能之一。当您获取新数据时(例如,当您在
sharedPreferences
中存储新文件时,您应该将更新推向适配器,以便它可以执行需要做的事情,并刷新如有必要。您甚至可以使其成为简单的update()
呼叫什么都没传递,并且适配器可以在OnBindViewHolder sharedPreferences
查找>,如果需要。而且,每次绘制列表中的项目时,它都会比进行这些查找要高得多(我真的建议您使用
sharedPreferences
,但也许会使事情复杂化不过,我仍然建议您在内部使用基本列表来尝试使您的适配器工作 - 不需要知道该应用程序的其余部分如何持续数据)onBindViewHolder
is the method the adapter calls when it's displaying the list, and it's passing you aViewHolder
so you can update it to display a particular item in the list.It's not the place to be doing stuff like calculating that the list has changed, and requesting a new layout, which is why you're getting an exception. You also definitely shouldn't be changing the
items
dataset while theRecyclerView
is trying to display part of it!Really, your adapter should have some kind of
setData
function, where you pass in updated data, and it can do stuff like working out what's moved, sorting the list for display, keeping a list of what's new and needs a highlight dot, etc. And that function can callnotifyDataSetChanged()
, or one of the more specific (and better) update functions as appropriate.When you get new data (e.g. when you're storing a new file in the
SharedPreferences
) that's when you should be pushing an update to the adapter, so it can do what it needs to do, and refresh if necessary. You can even make it a simpleupdate()
call that passes nothing, and the adapter does all theSharedPreferences
lookup you're currently doing inonBindViewHolder
, if you want. And it'll be a lot more efficient than doing these lookups every time an item in the list is drawn(I'd really recommend against what you're doing with
SharedPreferences
too, but maybe it complicates things less than I'm imagining. I'd still recommend trying to make your adapter work with a basic list internally, though - pass one in, so it doesn't need to know how the rest of the app is persisting data)