如何将资源传递给ViewModel



在这种情况下,您需要将Resources传递给ViewModelproperties,因此您必须将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)

最新更新