使用片段之间的参数进行正确的ViewModel初始化

时间:2020-04-24 18:45:04

标签: android android-fragments arguments fragment viewmodel

example显示了ViewModel的用法以及如何创建一个ViewModelFactory来初始化一个传递一个参数的ViewModel。该示例的末尾有一条注释:

Note: In this app, it's not necessary to add a ViewModelFactory for the ScoreViewModel, because you can assign the score directly to the viewModel.score variable. But sometimes you need the data right when the viewModel is initialized.

实际上,为了填充ScoreFragment的最终分数,它说要执行以下操作

binding.scoreText.text = viewModel.score.toString()

但是,这不正确吗? binding.scoreText.text是否不应该分配viewModel.score.value.toString()?在游戏结束时,如何避免使用ViewModelFactory在finalScore内通过ScoreFragmentViewModel提供的参数正确初始化GameFragment内的ScoreFragment变量?由于onCreateView仅显示最终得分而没有进行任何更改,因此为什么在最终代码示例中在ScoreFragment的{​​{1}}中添加了观察者?

    // Add observer for score
    viewModel.score.observe(viewLifecycleOwner, Observer { newScore ->
        binding.scoreText.text = newScore.toString()
    })

我还有一个简单的问题。 假设我有两个片段,第一个片段仅显示几个TextView,第二个片段用于编辑它们,因此第二个片段是唯一能够修改基础模型的片段,是否需要创建两个ViewModels?第二个片段应该使用调用片段的TextViews初始化,是否正在实现ViewModelFactory来初始化那些必不可少的字段,或者是否有更简单的机制来初始化它们?

1 个答案:

答案 0 :(得分:0)

您提到的示例当然具有教育意义,也许与实际项目并不相似。关于您的问题,我将尽我所能:

    示例中的
  1. ScoreViewModel仅包含一个值,并且它永远不会改变。因此,无需观察它的变化,这就是为什么该值不是LiveData且无需使用

    的原因

    viewModel.score.value.toString()

  2. 如果ViewModel在构造函数中没有参数,则可以跳过ViewModelFactory。因此,您可以使您的ScoreViewModel不带任何参数,但可以对字段“得分”使用某种公共设置器(并从ScoreFragment中将其设置为包中的最终得分)。在某些情况下,可能不建议这样做。我认为他们写了该说明来强调可用于初始化ViewModel的不同方案。也许不是很优雅:-)

  3. 我找不到您提到的下一个代码(该代码不应存在,因为无法观察到“得分”)

    viewModel.score.observe(viewLifecycleOwner, Observer { newScore -> binding.scoreText.text = newScore.toString() })

  4. 关于这两个片段,您的问题尚不清楚。如果希望他们共享一定范围的数据(相同的数据),则可以使用shared ViewModel。例如,共享的ViewModel可以包含两个LiveData字符串,然后第一个片段可以“显示”这些字符串(TextViews随便什么),第二个片段可以“编辑”它们