【问题标题】:What ViewModelStoreOwner to use for ViewModelProvider in Fragment?片段中的 ViewModelProvider 使用什么 ViewModelStoreOwner?
【发布时间】:2020-04-22 19:23:43
【问题描述】:

我创建了一个测试活动来更新 MyViewModel 中的一些文本。

我想在一个片段中观察这些变化,但是当我使用

MyViewModel myViewModel = new ViewModelProvider(this).get(MyViewModel.class);

它给了我一个与活动中使用的不同的 MyViewModel 实例,这导致我在片段中的 onChanged() 回调没有被调用。

仅当我将相同的片段代码修改为

HomeViewModel homeViewModel = new ViewModelProvider(getActivity()).get(HomeViewModel.class);

片段是否获得与活动相同的 MyViewModel 实例 - 因此成功调用了 onChanged()

但是,我不确定使用 getActivity() 作为 ViewModelStoreOwner 是否是正确的做事方式,因为我在任何地方的任何示例中都没有看到这一点。我想知道在这种情况下是否应该使用更好的 ViewModelStoreOwner?

【问题讨论】:

    标签: android android-fragments android-livedata android-viewmodel


    【解决方案1】:

    我想知道是否应该有更好的 ViewModelStoreOwner 在这种情况下使用?

    您应该使用activity 实例在同一活动中的片段之间共享同一实例。

    Activity 和Fragment 都实现了自己的ViewModelStoreOwner 接口并实现了getViewModelStore() 方法。 getViewModelStore() 提供ViewModelStore 实例,用于存储viewmodel 对象,由ViewModelProvider 创建。

    注意:ComponentActivity 实现了ViewModelStoreOwner 接口,FragmentActivity(AppCompatActivity 的父级)继承了实现。

    所以Activity和Fragment都有针对ViewModelStoreOwner接口方法的具体实现,并按照对象的lifecycle存储viewmodel实例(包括配置更改)。

    由于片段属于活动,因此获得相同的活动实例,因此使用getActivity() 将导致使用活动的ViewModelStoreOwner 对象。要在片段之间共享对象,只需使用活动实例创建ViewModelProvider,它将在所有片段中使用相同的ViewModelStoreOwner,因此将返回viewmodel 的持久对象(如果之前创建)。

    【讨论】:

    • Application 可以成为 ViewModelStoreOwner 吗?
    • @IgorGanapolsky 我验证了应用程序 API,这是不可能的。
    • @IgorGanapolsky 您可以使用 AndroidViewModel,如果需要,它可以访问 Application,但不能作为 ViewModelStoreOwner。
    【解决方案2】:

    拥有一个尽可能少做的Activity 已经成为一段时间以来的“最佳实践”,因此需要访问同一个ViewModel 实例的ActivityFragment 的场景可能没有被许多指南覆盖。

    但是“没有规则没有例外”,您的场景类似于Activity 有两个需要共享数据的Fragments。

    在这种情况下,使用Activity 范围为ViewModel 以确保每个组件都可以访问同一个实例。另请参阅 developer.android.com 的 View Model Overview 中的 "Share data between fragments" 部分

    【讨论】:

      【解决方案3】:

      我认为您收到错误不是因为您的 ViewModel 类。我删除了除了构造函数之外的所有代码,只保留了一个简单的类。它工作正常。如果您遵循 MVVM 模式,那么您可能会因为数据库实现而出错,或者您可能会检查存储库。

      【讨论】:

      • OP的问题的解决方案是什么?
      猜你喜欢
      • 1970-01-01
      • 2020-05-21
      • 2021-04-03
      • 2019-06-14
      • 1970-01-01
      • 2018-10-19
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      相关资源
      最近更新 更多