当前位置: 首页 > 知识库问答 >
问题:

Android RecolyerView冻结notifyDataSetChanged调用的UI

楚嘉玉
2023-03-14

我知道有很多关于这个话题的问题,但我还是找不到一个解决办法。

我有一个应用程序,可以加载和显示图像(就像智能手机上的常规图库应用程序一样)

我加载了背景中的所有图像与协同线-在这个过程的这个阶段没有问题。

当我通知适配器有关数据时就会出现问题。notifyDataSetChanged()调用会冻结UI一段时间。

我们讨论的是相对较大的网格(例如1000+张照片)

其他线程中的几乎所有答案都建议,我应该检查更改了哪些项,并调用notifyItemChanged(索引),而不是调用notifyDataSetChanged()或使用DiffUtil或类似的东西。我理解所有这些,但在RecyclerView初始化时(当应用程序加载时)没有现有数据,因此我看不到调用notifyDataSetChanged()的其他选项。

问候,我

共有1个答案

何涵育
2023-03-14

null

你说:

“在RecyclerView初始化时(当应用程序加载时)没有现有数据,因此我看不到调用notifyDataSetChanged()的其他选项。”

我不能百分之百肯定我明白你的意思,但我相信你正在经历的是:

  1. 应用程序启动,您设置了适配器/RecyclerView,但仍然没有数据;您还可以从ViewModel中观察到一些LiveData > list或类似内容。
  2. 您向ViewModel请求数据,该ViewModel以某种方式挂起,并将列表 与适配器的数据异步传递。
  3. 从适配器接收到列表 后,可以通过添加的某些方法(如adapter.SetData(list))设置该列表,然后调用adapter.NotifyDataSetChanged()

这要花很长时间。

其他线程建议您使用diffutil()(或其asyncdiffutil版本)的原因是这有助于适配器使用...通过计算需要适配器的内容和相同的内容,使数据适应视图(holder)。

我们(到目前为止)还没有看到您的适配器,但我猜测您正在扩展recyclerView.Adapter 。这意味着您应该做自己的DiffUtil(或Async)。

或者,您也可以扩展ListAdapter ,其中T是您的数据类型(List ),而K是您的查看器类型,如果我没有记错的话,您可以使用RecyclerView.ViewHolder(然后让您的查看器对其进行扩展)。

此列表适配器强制您在构造函数中提供DiffUtil。

仅仅检查两个(空的)列表之间的差异是没有意义的

其实并不是,在框架已经为您提供了解决方案的情况下,您正在制造一个问题。DiffUtil不会更慢(减去几毫秒?)如果列表是空的,那么它将没有什么可比较的。但是当有数据的时候,它会为你做重物。

无论如何,在你发布一些代码之前,我们都是在凭空说话。:)

 类似资料:
  • 问题内容: 我有一个非常小的.so文件(可在此处找到:https ://docs.google.com/leaf?id=0B4MxFm- ACB3INjhkMjhlNzktYzkxYy00Zjk5LTk0Y2MtZDE2MWQ2MzY1OWUy &hl=zh_CN& authkey =CMrJguwN) 我试图将其加载到RHEL上的Java中,而Java 只是冻结(没有错误或异常)。我在LD_LI

  • 当数据被不可变地借用时,它还会冻结(freeze)。已冻结(frozen)数据无法通过原始对象来修改,直到指向这些数据的所有引用离开作用域为止。 fn main() { let mut _mutable_integer = 7i32; { // 借用 `_mutable_integer` let _large_integer = &_mutable_

  • 问题内容: 我有一个自定义适配器,可显示订单列表中的每一行。 从Web服务查询新的订单列表之后,我想更新ListView的内容,因此我让Activity在调用notifyDataSetChanged()之前进行更新。 但是,从不调用OrderRowAdapter的getView()方法。ListView永远不会更新。 问题答案: 原来我不被叫的问题是因为它不可见。我的布局XML已经上与它的高度。因

  • 问题内容: 我有一个程序在其中加载文件,同时显示一个窗口以通知用户正在加载文件。我决定制作一个FileLoader类,它是一个实际上处理了文件加载的SwingWorker类,以及一个实现PropertyChangeListener的ProgressWindow,用于通知用户传递给它的SwingWorker的状态。 我的代码当前如下所示: 问题是,每当我调用loader.get()时,它都会冻结GU

  • 我正在为一个班做一个基本的乒乓球游戏。我让Pong工作,启动时有一个GUI显示,不幸的是,我似乎无法从开始按钮启动游戏。我已经在代码上注释了问题所在,并删除了不相关的代码。 有什么想法吗?

  • 问题内容: 这是一个片段 我正在使用和作为文本框。文本框应显示“ Hello”,然后等待一秒钟,但是,当我尝试执行此操作时,它会等待一秒钟,然后放置“ Hello”一词,这不是我想要的。 我不确定为什么会这样,因为我将其按逻辑顺序放置。如果有人可以帮助我,那就太好了。 编辑: 有谁知道替代方案,所以我可以使用“延迟”效果吗? 问题答案: 永远不要从Swing事件线程中调用Thread.sleep(