根据此article:
ViewModel应该公开View的状态,而不仅仅是 事件。
我正在重用视图模型,因为我需要用于多个视图的相同数据,但我对此感到怀疑的是,它们使用相同的数据,但是它们以不同的方式显示 。例如,如果我有一个用户列表,则第一个视图显示他们,第二个视图使用数据用于排序,如果用户列表达到特定大小,则第三视图会显示一些标签。
如果我只公开数据(用户列表),并且视图将决定要执行的操作,除了违反架构外,还很难测试,因为我需要模拟android,但我只要测试是否调用了某个方法,视图的显示方式无关紧要。
所以我在考虑解决方案,例如为每个使用viewmodel的视图创建一个State类,以便该viewmodel更新状态,现在我可以轻松地测试状态是否发生变化。
我的问题是,重用视图模型的视图越多,每个视图的状态就越多,这在我看来也不是一件容易的事,只需想象一下即使一个视图中只有1个视图,该方法也会更改所有状态。时间可以显示。
为每个视图创建单独的视图模型就像为我复制代码一样,例如:ResetPasswordView
和CreatePasswordView
,它们都具有相同的过程,行为也几乎相同,所以为什么不重用viewmodel ? ...还是我应该?我在这里想念什么?
编辑(我当前的解决方案):
根据我的操作,我为每个片段/活动创建了单独的视图模型,因为尽管它们使用相同的数据,但它们表示的方式不同。这样,我就可以对表示逻辑进行单元测试,因为所有数据操作(特定于视图)都在视图模型上进行。
我确实共享视图模型,但是出于导航目的,示例是解释此视图的最佳方法(我在这里使用Koin作为我的依赖框架):
OnBoardingActivity :
class OnBoardingActivity {
var fullNameViewModel by viewModel<FullNameViewModel>()
private fun initViewModels() {
fullNameViewModel.stateShowEmail.observe(this, Observer {
// do navigate to email because that's the next screen/fragment after FullNameFragment
})
}
}
FullNameFragment :
class FullNameFragment {
var viewModel by sharedViewModel<FullNameViewModel>() // notice that I share the view model from the activity here to have only 1 instance
private fun initViews() {
RxTextView.textChanges(etFirstName)
.doOnNext { viewModel.setFirstName(it.toString()) }
.subscribe()
// ... set the other fields
}
private fun initViewModels() {
viewModel.stateValidationFirstName.observe(this, Observer {
when(it) { // validation
is RequiredValidation -> // show some error/validation message
else -> it is valid! remove any error/validation messages
}
})
}
}
FullNameViewModel :
class FullNameViewModel {
val stateValidationFirstName = MutableLiveData<Validation>() // some validation object
val stateShowEmail = SingleLiveEvent<Any>() // I'm using the hacky single live event here hehe
fun setFullName() {
// do the validations, some process and this can be easily test
// like: stateValidationFirstName = RequiredValidation()
stateShowEmail.call()
}
}
答案 0 :(得分:1)
通常,当文章引用视图时,它们并不意味着文字View
类。他们是从建筑意义上讲的。
以MVVM为例。模型-视图-视图模型。
当我们谈论Android时,视图是Activity
,Fragment
和View
布局。
因此理想情况下,对于最合乎逻辑的集合,您应该有一个ViewModel
。
如果您有一个Activity
和一个布局,但没有Fragment
,那么有意义的是有一个ViewModel
来覆盖Activity
状态,其中包括其布局
如果您有一个Activity
及其自己的布局和一个Fragment
,则可能有两个ViewModel
。一个用于Activity
状态,另一个用于Fragment
。
我编写了一个示例应用程序,可能会有所帮助: https://github.com/DavidEdwards/mvvm-example
以具有基本Activity
且除Fragment
以外没有布局的示例为例。 ViewModel
中会有一个Fragment
(通常,这绝不是规则)。在此ViewModel
中,您将有LiveData
代表您的View
的状态。当您想更改View
的状态时,可以在ViewModel
中更改状态,然后ViewModel
会将更改传播到View
。通常,我会使用出色的Android Databindings Library将ViewModel
传递到我的布局中来完成此任务。