【问题标题】:Sharing one instance of ViewModel across different Fragments in a screen在屏幕中的不同 Fragment 之间共享一个 ViewModel 实例
【发布时间】:2020-03-25 23:28:57
【问题描述】:

我正在使用单个活动模式,并且在一个特定屏幕中,我想与两个不同的片段共享一个视图模型。经过一番研究,我找到了以下解决方案:

  1. 我在创建视图模型时使用了活动实例,因此我的两个片段都获得了相同的实例。但这种方法的缺点是,viewModel 实例在应用程序运行之前将一直处于活动状态。
ViewModelProviders.of(Activity.this, viewModelFactory).get(CustomViewModel::class.java)
  1. 我可以在启动第一个片段时向第一个片段添加标签,并在第二个片段中创建 viewModel 时传递第一个片段的实例。这样,我将在两个片段之间共享一个 ViewModel 实例。 ViewModelProviders.of(fragmentManager?.findFragmentByTag(TAG)!!, viewModelFactory).get(CustomViewModel::class.java)

  2. 我在某处又阅读了一种方法来共享 viewModel,但我忘记了,因为它对我不起作用。

我想知道哪种方法最适合在片段之间共享 viewModel。我在这里有什么选择?谢谢。

【问题讨论】:

  • 你打破了 MVVM 模式,它的重点是视图模型与其对应视图之间的 1:1 关系。
  • 如果您还使用导航组件,您可以按导航图级别确定视图模型的范围。
  • 嘿@MarkFeldman 我理解你的意思,但是如果它们都使用相同的数据,那么为两个不同的片段创建一个视图模型是合乎逻辑的。我还有另一个屏幕,我在其中使用了四个片段。在该屏幕中创建四个视图模型似乎不是一个好主意,尤其是当所有片段都使用相同的数据时。同样根据developer.android.com/topic/libraries/architecture/viewmodel 中的视图模型描述,单个视图模型可用于共享数据 b/w 片段。 .
  • 嘿@AndreClassen 谢谢。我目前没有在应用程序中使用导航图。实现导航图后一定会试一试。
  • 这似乎合乎逻辑,但它不是 MVVM。视图是 GUI 的 声明性 元素,而视图模型是视图状态的抽象;数据绑定将它们结合在一起。如果您有必须由多个视图表示的数据,那么它应该在您的模型层中,并且多个视图模型实例将该数据公开给它们的关联视图。如果您不将它们抽象到您的视图模型层中,则无法对您的多个视图都和平共存(例如)进行单元测试。

标签: java android kotlin mvvm


【解决方案1】:

根据docs 以下是如何与多个片段共享同一个 ViewModel。

model = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.java]
    } ?: throw Exception("Invalid Activity")

它在文档中的解释如下:

请注意,两个片段都会检索包含它们的活动。这样,当每个 Fragment 获得 ViewModelProvider 时,它们都会收到相同的 SharedViewModel 实例,该实例的作用域是这个活动。

[更新] 您可以在片段中使用 kotlin 属性委托

private val model: SharedViewModel by activityViewModels()

Official docs

【讨论】:

  • 这已被弃用?
【解决方案2】:

首先添加这些依赖来激活视图模型生命周期委托:

实现“androidx.fragment:fragment-ktx:1.3.6”

然后在您的片段类中使用这样的视图模型:

private val viewmodel: SearchFragmentViewModel by activityViewModels()

如果您使用匕首,请参阅this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多