在适配器内交换元素

发布于 2025-01-25 13:33:04 字数 1131 浏览 2 评论 0原文

我正在制作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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那小子欠揍 2025-02-01 13:33:04

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 a ViewHolder 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 the RecyclerView 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 call notifyDataSetChanged(), 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 simple update() call that passes nothing, and the adapter does all the SharedPreferences lookup you're currently doing in onBindViewHolder, 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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文