【问题标题】:When getting the ViewModel in a fragment, should I provide "viewModelStore" or "this" as the ViewModelStore to the ViewModelProvider() method在片段中获取 ViewModel 时,我应该将“viewModelStore”还是“this”作为 ViewModelStore 提供给 ViewModelProvider() 方法
【发布时间】:2020-03-10 00:29:16
【问题描述】:

在我的片段类中,当我获得我的 viewModel 时,我可以用两种不同的方式编写我的代码。

  • 使用“viewModelStore”
ViewModelProvider(viewModelStore, viewModelFactory).get(FragmentViewModel::class.java)
  • 使用“这个”
ViewModelProvider(this, viewModelFactory).get(FragmentViewModel::class.java)

我的问题是,这两种选择之间是否存在任何差异,如果是,哪一种是更可取的方法?

【问题讨论】:

    标签: android android-fragments mvvm viewmodel android-viewmodel


    【解决方案1】:

    如果您提供自己的ViewModelProvider.Factory,则没有区别,所以只需使用更简单的this

    当然,如果您在 Kotlin 中,则根本不需要直接使用 ViewModelProvider,而是要使用 Fragment KTX 并使用

    val viewModel: FragmentViewModel by viewModels { viewModelFactory }
    

    请注意,如果您使用自己的工厂,则应始终传入ViewModelStoreOwner(即this)而不是仅传入ViewModelStore,因为the Javadoc明确提到:

    如果所有者实现HasDefaultViewModelProviderFactory,此方法将使用default factory。否则,将使用ViewModelProvider.NewInstanceFactory

    ViewModelStore 构造函数无法获取正确的默认工厂。

    【讨论】:

    • 谢谢,解释得很好,我想我现在明白了,我没有任何理由使用 viewModelStore,如果我不提供自己的工厂,那甚至是错误的。因此,我永远不会在这种情况下使用它。对于直接在 by viewModels 中传递 viewModelFactory,我认为必须事先制作工厂,因此必须进行某种依赖注入,对吗?
    • 注入工厂当然是一个常见的用例(例如,在测试时提供模拟 ViewModel),但不是使用自定义工厂的要求 - 您可以使用它来传递一些特定的变量到 ViewModel 的构造函数中
    • 我就是这样做的,使用工厂将一些变量传递给我的 ViewModel,但是我主要是问在我的 ViewModel 中,目前我不能只调用 viewModels { viewModelFactory },因为那个工厂不存在观点。我在片段的 onCreate 方法中创建了它的一个对象,因此我无法访问类顶层的工厂。所以我说,为了做到这一点,我希望它必须注入 DI。如果没有,那我怎么才能访问不是工厂对象?
    • 它在 lambda({ })中的原因是它在您第一次访问 ViewModel 之前不会评估 lambda。这意味着它适用于 lateinit var 工厂。
    • 哦,哇,我也不知道。非常感谢您提供的所有信息!我现在已经通过将我的工厂创建为 val 对其进行了测试,但它是创建的 by lazy,然后我按照您的建议在 by viewModels 中使用该工厂,它工作得很好。我不知道这是否被认为是一种好的做法,但我的 onCreateView 在我看来更加清晰易读。
    猜你喜欢
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2010-10-30
    • 2013-05-13
    相关资源
    最近更新 更多