Loading... ## 简介 ViewModel是Jetpack中最重要的组件之一。传统开发模式下,Activity的任务实在太重了,既要负责逻辑处理,又要控制UI展示,甚至要处理网络回调。这是不符合软件设计模式的要求的,随着项目的不断扩大,这个项目会变得越来越难以维护。因为它在架构上是失败的。 ViewModel的一个重要作用就是分担Activity的一部分工作。即用于专门储存和管理用户界面相关的数据。这样Activity只需要承担UI控制器的职能。 另外,ViewModel还有一个关键的特性,ViewModel的生命周期和Activity不同,它可以保证在手机屏幕发生旋转时不会被重建,只有当Activity退出时才会跟着Activity一起销毁。因此将于界面相关的变量存放在ViewModel当中,这样即使旋转屏幕,界面上的数据也不会丢失。 ---------- ## 不传入参数的使用 #### 1. 添加依赖 在build.gradle(module:app)的dependencies块内,添加 ```gradle implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' ``` #### 2. 新建ViewModel的拓展类 ```kotlin class GameViewModel : ViewModel() { ... } ``` #### 3. 在片段(UI控制器)中添加ViewModel的引用 ```kotlin private lateinit var viewModel: GameViewModel ``` #### 4. 初始化ViewModel 在配置更改(例如屏幕旋转)期间,将重新创建UI控制器(例如片段)。但是,ViewModel实例仍然存在。如果ViewModel使用ViewModel该类创建实例,则每次重新创建片段时都会创建一个新对象。所以使用ViewModelProvider来创建ViewModel实例。它会保证单例。 ```kotlin viewModel = ViewModelProvider(this).get(GameViewModel::class.java) ``` #### 5. 在UI控制器中使用 经过以上设置,即可在UI控制器中调用ViewModel的方法来操纵数据,需要数据的地方直接访问ViewModel即可。 ---------- ## 传入参数的使用 #### 1. 1. 添加依赖 在build.gradle(module:app)的dependencies块内,添加 ```gradle implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' ``` #### 2. 新建ViewModel的拓展类 注意其有构造函数有参数 ```kotlin class ScoreViewModel(finalScore: Int) : ViewModel() { var score = finalScore ... } ``` #### 3. 新建一个实现ViewModelProvider.Factory接口的类。 它是工厂类,给它构造函数添加一个参数(与前一步对应) ```kotlin class ScoreViewModelFactory(private val finalScore: Int) : ViewModelProvider.Factory { } ``` #### 4. 添加上一步的具体实现 ```kotlin override fun <T : ViewModel?> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(ScoreViewModel::class.java)) { return ScoreViewModel(finalScore) as T } throw IllegalArgumentException("Unknown ViewModel class") } ``` #### 5. 在UI控制器中添加ViewModel相关变量 ```kotlin private lateinit var viewModel: ScoreViewModel private lateinit var viewModelFactory: ScoreViewModelFactory ``` #### 6. 初始化viewModel工厂变量 其中的ScoreFragmentArgs 是自动生成的类。如果当前UI控制器有参数,就会生成这样一个Args类 ```kotlin viewModelFactory = ScoreViewModelFactory(ScoreFragmentArgs.fromBundle(arguments!!).score) ``` #### 7. 使用工厂类构建viewModel变量 ```kotlin viewModel = ViewModelProvider(this, viewModelFactory).get(ScoreViewModel::class.java) ``` #### 8. 在UI控制器中使用 经过以上设置,即可在UI控制器中调用ViewModel的方法来操纵数据,需要数据的地方直接访问ViewModel即可。 最后修改:2020 年 06 月 03 日 09 : 17 AM © 允许规范转载