在Android中,ViewModel
是一种用于管理与UI相关的数据的架构组件。它的生命周期与 Activity
或 Fragment
的生命周期相独立,能够有效地处理配置更改(如旋转屏幕)而不会丢失数据。以下是创建 ViewModel
的几种常见方式。
1. 使用 ViewModelProvider
这是最常用的方式,适用于 Activity
和 Fragment
。
1.1 在 Activity
中创建 ViewModel
定义一个自己的 ViewModel 类:MyViewModel
class MyViewModel: ViewModel() { }
在 Activity 中创建 MyViewModel 的对象,关键代码:ViewModelProvider(this).get(MyViewModel::class.java)
class MyActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
}
}
1.2 在 Fragment
中创建 ViewModel
在 Fragment 中创建 MyViewModel 的对象,也是使用 ViewModelProvider。 关键代码:ViewModelProvider(requireActivity()).get(MyViewModel::class.java)
class MyFragment : Fragment() {
private lateinit var viewModel: MyViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewModel = ViewModelProvider(requireActivity()).get(MyViewModel::class.java)
return inflater.inflate(R.layout.fragment_my, container, false)
}
}
2. 使用 ViewModelFactory
如果需要传递参数给 ViewModel
,可以使用 ViewModelFactory
。
2.1 创建 ViewModel
和 ViewModelFactory
ViewModelFactory 用来自定义创建 ViewModel 的过程,可以用于往ViewModel的构造方法中传递参数
class MyViewModel(private val someParam: String) : ViewModel() {
// ViewModel 的逻辑
}
class MyViewModelFactory(private val someParam: String) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
return MyViewModel(someParam) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
2.2 在 Activity
或 Fragment
中使用 ViewModelFactory
还是使用了 ViewModelProvider,只不过多传递了 ViewModelFactory 参数。关键代码是:ViewModelProvider(this, factory).get(MyViewModel::class.java)
class MyActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val factory = MyViewModelFactory("Some parameter")
viewModel = ViewModelProvider(this, factory).get(MyViewModel::class.java)
}
}
3. 使用 by viewModels()
委托
Android官方基于 kotlin 语言特性,提供了一些方便的扩展库,可以用来简化 ViewModel 的创建过程。比如 by viewModels()
3.1 添加扩展库依赖
在 build.gradle(module级别) 中添加扩展依赖:⬇️
dependencies {
implementation("androidx.activity:activity-ktx:1.9.3")
implementation("androidx.fragment:fragment-ktx:1.8.5")
}
3.2 在Fragment 中使用 by viewModels()
在 Fragment
中,可以使用 by viewModels()
委托来简化 ViewModel
的获取。
class MyFragment : Fragment() {
private val viewModel: MyViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_my, container, false)
}
}
3.3 在 Activity 中使用 by viewModels()
在 Activity
中,可以使用 by viewModels()
委托来简化 ViewModel
的获取。
class MyActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
4. 总结
ViewModelProvider
是创建ViewModel
的基本方式。ViewModelFactory
可以用于传递参数给ViewModel
。by viewModels()
委托提供了一种更简洁的方式来获取Fragment
中的ViewModel
。