RecyclerView Adapter内的Android ViewModel用于懒惰的数据库下载

时间:2018-08-22 20:39:23

标签: android mvvm android-recyclerview viewmodel

我有一个问题与MVVM的正确设计和体系结构有关,而不是与编码本身有关。在我的项目中,我遇到的情况是ViewModel上提供数据,后来在RecyclerView.Adapter中使用这些数据来创建正确的视图。

但是我不知道这是否正确(从正确的“做事方式” POV)是否将某些数据以ID的形式提供以进一步从Room或外部服务器获取?例如,在onBindViewHolder期间,使用带有live()的LiveData可以在满载时更新某些字段。

2 个答案:

答案 0 :(得分:3)

在视图中提取数据是不行的。它违背了MVVM的宗旨,尤其是Android Jetpack的努力。主要原因之一是数据需要保留配置。在视图中放置“数据获取”机制会失败,因为可以在需要时随时破坏和重新创建视图。

因此,我建议您确保对网络或与此有关的任何其他数据源的所有调用都围绕ModelView而不是视图。让虚拟机通过观察者将数据馈送到视图。

我刚才所说的例外是用例,例如用Picasso或Glide加载图像,然后在其中输入URL并加载图像。但这是另一回事,因为它们旨在处理这些问题。

更新后续问题

  

在绑定过程中是否可以将observe()仍放在适配器中?

不!发送到适配器的数据必须符合预期的用途。例如,如果您必须执行“待办事项”应用程序,并且“顶级活动”显示所有待办事项,则必须供稿适配器完成数据(标题,创建时间等)。

不应获取将不会显示的数据(例如描述或子列表),并且不需要标识特定的数据(除非您仅出于避免以下目的而存储它们)第二个网络呼叫,并将它们作为序列化数据传递给下一个活动。

当用户单击特定的待办事项时,然后使用其自己的ViewModel启动新活动,该模型将获取该活动的详细信息(假设您通过意图传递了一些ID)。

  

如果是第一个,那么我了解到observe()不仅应该更新数据,而且还应稍后将其填充到Observer并调用notifyDataSetChanged(),对吧?

观察是一种在数据已更改或旧视图被破坏时将数据发布到视图的方法,因此,将为新视图提供在“视图死亡”后仍然有效的旧数据。因此,在同一方法中,应该完成适配器数据的更新,并因此调用notifyDataSetChanged()或类似方法。

我希望这很清楚。

答案 1 :(得分:1)

我认为最好将ViewModel与适配器分开。从我收集的数据中,您基本上希望通过让每个列表项观察该项目的特定ID来从Room加载其自身的数据。这听起来效率很低,因为您基本上是让每个项目都在数据库(或网络呼叫)上执行查询以仅检索将要显示的所有项目的一个项目,请考虑一下如果显示100,它将如何缩放项目。我认为最好只执行一个查询以获取数据列表并将数据设置为适配器中的列表项,这很简单。请注意,onBindViewHolder()不仅会在滚动屏幕时被调用一次,还会被多次调用,因此如果您试图延迟加载每个列表项,它会变得很丑陋。