ViewModel的一个重要作用就是帮助Activity分担一部分工作,专门用于存放与界面相关的数据,只要是界面上能看得到的数据,它的相关变量都应该存放在ViewModel中
ViewModel的生命周期和Activity是不同的,在手机屏幕旋转的时候,Activity会被重新创建,但是ViewModel不会,只有Activity退出的时候,ViewModel才会和Activity一起销毁
image-20210818212407408
ViewModel的基本用法
通常比较好的编程规范是给每一个Activity和Fragment都创建一个ViewModel
下面的程序可以做到在屏幕旋转的时候,界面上显示的数字是不变的
创建一个ViewModel类:
1 2 3
| class MainViewModel : ViewModel() { var counter = 0 }
|
绑定MainActivity和MainViewModel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
val countReserve = sp.getInt("count_reserved",0)
viewModel = ViewModelProvider(this)[MainViewModel::class.java] plus_one.setOnClickListener { viewModel.counter++ refreshCounter() } refreshCounter() }
private fun refreshCounter(){ infoText.text = viewModel.counter.toString() } }
|
向ViewModel传递参数
下面的程序可以做到除了以上的功能外,还可以在退出程序后,重新打开的时候,界面显示的数字还是和之前一致的
重新更改MainViewModel的内容,添加一个参数:
1 2 3 4
| class MainViewModel(val countReserve : Int) : ViewModel() { var counter = countReserve }
|
需要一个ViewModelProvider.Factory来为ViewModel传递参数(还是不能直接使用ViewModel的构造方法)
1 2 3 4 5 6 7
| class MainViewModelFactory(private val countReserve : Int) : ViewModelProvider.Factory { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return MainViewModel(countReserve) as T
} }
|
更改MainActivity中的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel lateinit var sp : SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
sp = getPreferences(MODE_PRIVATE)
val countReserve = sp.getInt("count_reserved",0)
viewModel = ViewModelProvider(this,MainViewModelFactory(countReserve))[MainViewModel::class.java]
plus_one.setOnClickListener { viewModel.counter++ refreshCounter() }
clear_btn.setOnClickListener { viewModel.counter = 0 refreshCounter() } refreshCounter()
}
override fun onPause() { super.onPause() sp.edit { putInt("count_reserved", viewModel.counter) } }
private fun refreshCounter(){ infoText.text = viewModel.counter.toString() } }
|