在这种情况下,您需要将Resources
传递给ViewModel
的properties
,因此您必须将Resources
作为argument
传递给constructor
。
ViewModel
class WorkoutListViewModel(private val resources: Resources) : ViewModel(){
private var _part :MutableLiveData<String> = MutableLiveData()
private var _list : MutableLiveData<List<String>> = MutableLiveData(arrayListOf())
private val workoutListSource : WorkoutListSource by lazy { WorkoutListLocalSource(resources) }
val list = _list
val part = _part
fun setList(part : String) {
_part.value = part
when(_part.value) {
"CHEST" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.CHEST)
"BACK" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.BACK)
"LEG" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.LEG)
"SHOULDER" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.SHOULDER)
"BICEPS" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.BICEPS)
"TRICEPS" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.TRICEPS)
"ABS" -> _list.value = workoutListSource.getWorkoutListByPart(BodyType.ABS)
}
}
}
界面
interface WorkoutListSource {
fun getWorkoutListByPart(type: BodyType) : List<String>
}
接口的实现
class WorkoutListLocalSource(_resources: Resources) : WorkoutListSource {
private val resource: Resources = _resources
override fun getWorkoutListByPart(type: BodyType): List<String> {
return resource.getStringArray(type.getResourceId()).toList()
}
}
这是我写的代码
但是这个代码一定是错的。
开发人员文档说ViewModel
不应该引用Android platform
。
然而,我在ViewModel
中传递Resources
作为argument
。
我认为这部分是错误的,但我不知道如何正确地修理它。
更新
片段
class WorkoutListTabPageFragment : Fragment() {
private var _binding : FragmentWorkoutListTabPageBinding? = null
private val binding get() = _binding!!
private val viewModel: WorkoutListViewModel by viewModels { WorkoutListViewModelFactory(resources) }
}
你可以使用AndroidViewModel代替ViewModel。如果你唯一的构造函数参数是Application,你甚至不需要为它创建一个工厂。
class WorkoutListViewModel(application: Application): AndroidViewModel(application) {
private val resources = application.resources
//...
}
和代码简化提示:
fun setList(part : String) {
_part.value = part
_list.value = workoutListSource.getWorkoutListByPart(BodyType.valueOf(part))
}
虽然我认为有这么多主体部分(将来可能会添加更多)有助于将类型作为存储库中的数据处理,而不是将它们硬编码为枚举值。无论哪种方式,最好只使用枚举或字符串,这样你就不必来回转换了。
创建一个ViewModelFactory类并传入ViewModel的起始数据。
ViewModelFactory
class MyFragmentViewModelFacotry(private val resources: Resrouces) : ViewModelProvider.Factory {
override fun<T : ViewModel?> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(MyFragmentViewModel::class.java)) {
return MyFragmentViewModel(resources) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
视图模型
class ViewModel(private val resources: Resources) : ViewModel() {
...
}
使用ViewModelFactory创建ViewModel,在Activity或Fragment中运行以下命令
val viewModelFactory: MyViewModelFactory = MyViewModelFactory(resources)
val viewModel = ViewModelProvider(this, viewModelFactory).get(MyViewModel::class.java)