如何将资源传递给 ViewModel
How can I pass Resources to ViewModel
这种情况需要将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。如果你唯一的构造函数参数是应用程序,你甚至不需要为它创建一个工厂。
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 class 并传入 ViewModel 的起始数据。
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)
这种情况需要将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。如果你唯一的构造函数参数是应用程序,你甚至不需要为它创建一个工厂。
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 class 并传入 ViewModel 的起始数据。
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)