在 Android Kotlin 中,给 ViewModel 传值有多种方式。这里列出了几种常见的方式:
- 使用 ViewModel 的构造函数传值:可以在 ViewModel 的构造函数中添加需要传递的参数,然后在创建 ViewModel 的时候传入相应的值。例如:
class MyViewModel(val param: String) : ViewModel() {
// ViewModel 的逻辑代码
}
在创建 ViewModel 的时候,需要传入 param 参数:
val viewModel = ViewModelProvider(this, ViewModelFactory("myParam")).get(MyViewModel::class.java)
- 使用 LiveData 传递数据:将需要传递的数据封装在 LiveData 中,然后在 ViewModel 中使用 LiveData。例如:
class MyViewModel : ViewModel() {
private val _data = MutableLiveData()
val data: LiveData = _data
fun setData(value: String) {
_data.value = value
}
}
在 Activity 或 Fragment 中观察 LiveData,获取数据:
viewModel.data.observe(this, Observer { data ->
// 获取数据并处理
})
然后在需要传递数据的地方,调用 setData 方法设置数据即可。
- 使用 Bundle 传递数据:使用 Bundle 将数据打包传递给 ViewModel。例如:
在 Activity 或 Fragment 中创建 Bundle,然后通过 ViewModelProvider 创建 ViewModel 时传递:
val bundle = Bundle().apply {
putString("param", "myParam")
}
val viewModel = ViewModelProvider(this, ViewModelFactory(bundle)).get(MyViewModel::class.java)
在 ViewModelFactory 中获取 Bundle 中的参数,创建 ViewModel:
class ViewModelFactory(private val bundle: Bundle?) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return if (modelClass == MyViewModel::class.java) {
val param = bundle?.getString("param") ?: ""
MyViewModel(param) as T
} else {
throw IllegalArgumentException("ViewModel Not Found")
}
}
}
4.如何往ViewModel中传入全局Application?
方法一
如果你想在 ViewModel 中访问 Application 对象,可以通过自定义 ViewModelProvider.Factory 实现传递 Application。
首先,创建一个继承自 ViewModel 的自定义 ViewModel 类,构造函数接受 Application 对象作为参数。例如:
class MyViewModel(application: Application) : AndroidViewModel(application) {
// ViewModel 的逻辑代码
}
接下来,创建一个继承自 ViewModelProvider.Factory 的自定义工厂类,用于实例化自定义的 ViewModel。在该工厂类中,通过构造函数接受 Application 对象,并将其传递给自定义 ViewModel 的构造函数。
class MyViewModelFactory(private val application: Application) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
return MyViewModel(application) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
然后,在你的 Activity 或 Fragment 中,通过 ViewModelProviders.of() 方法使用自定义的工厂类来获取 ViewModel。将 Application 对象作为参数传递给工厂类的构造函数
val viewModel = ViewModelProviders.of(this, MyViewModelFactory(application)).get(MyViewModel::class.java)
这样,你就可以在 ViewModel 中访问 Application 对象了。
请注意,以上示例中使用了 ViewModelProvider 的旧 API。自 Android Architecture Components 2.2.0 版本起,推荐使用 ViewModelProvider 的新 API,例如 ViewModelProvider(ViewModelStoreOwner, Factory)。同样的原理仍适用,只需要将自定义的工厂类传递给新 API 中的 Factory 参数即可。
方法二
class MyViewModel(application: Application) : ViewModel() {
// ViewModel的逻辑代码
class ViewModelFactory(private val application: Application) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return if (modelClass.isAssignableFrom(BlurViewModel::class.java)) {
MyViewModel(application) as T
} else {
throw IllegalArgumentException("Unknown ViewModel class")
}
}
}
}
class BlurActivity : AppCompatActivity() {
// 然后在Activity或Fragment中实例化ViewModel
private val viewModel: BlurViewModel by viewModels {
ViewModelFactory(
application
)
}
}
这些都是在 Android Kotlin 中给 ViewModel 传值的常见方式,选择适合自己的方式即可。
viewmodel 和 androidviewmodel的区别
ViewModel
和 AndroidViewModel
是 Android Jetpack 中的两个关键类,用于帮助在 Android 应用程序中管理 UI 相关的数据和状态。
ViewModel:
- ViewModel 是一个抽象类,用于存储和管理与 UI 相关的数据。
- ViewModel 的目的是在配置更改(如屏幕旋转)等情况下保持数据的一致性,并且在
Activity
或Fragment
销毁和重新创建时保留数据。 - ViewModel 不依赖于
Android Framework
,因此可以在任何 Java 或 Kotlin 环境中使用,不仅限于 Android 应用程序。 - 在 ViewModel 中,你可以使用
LiveData
、RxJava
或其他数据流框架来处理数据的变化和观察。
AndroidViewModel:
- AndroidViewModel 是
ViewModel
的子类,专门用于在 Android 应用程序中与 Context 相关的场景。 - AndroidViewModel 的构造函数接受
Application
对象作为参数,可以通过它访问应用程序的全局上下文。 - AndroidViewModel 继承自
ViewModel
,并添加了对Application
上下文的引用。 - 使用 AndroidViewModel 可以方便地在
ViewModel
中访问Application
对象,例如获取资源、执行数据库操作等。 - 与 ViewModel 类似,你可以在
AndroidViewModel
中使用LiveData
、RxJava
或其他数据流框架来处理数据的变化和观察。
在使用
ViewModel
和AndroidViewModel
时,通常遵循以下准则:
如果你只需要在ViewModel
中处理数据,并且不需要访问Android Framework
的特定功能,则可以使用ViewModel
。
如果你需要在ViewModel
中访问Application
对象或执行与Context
相关的操作,则可以使用AndroidViewModel
。