简介

ViewModel是Jetpack中最重要的组件之一。传统开发模式下,Activity的任务实在太重了,既要负责逻辑处理,又要控制UI展示,甚至要处理网络回调。这是不符合软件设计模式的要求的,随着项目的不断扩大,这个项目会变得越来越难以维护。因为它在架构上是失败的。
ViewModel的一个重要作用就是分担Activity的一部分工作。即用于专门储存和管理用户界面相关的数据。这样Activity只需要承担UI控制器的职能。

另外,ViewModel还有一个关键的特性,ViewModel的生命周期和Activity不同,它可以保证在手机屏幕发生旋转时不会被重建,只有当Activity退出时才会跟着Activity一起销毁。因此将于界面相关的变量存放在ViewModel当中,这样即使旋转屏幕,界面上的数据也不会丢失。


不传入参数的使用

1. 添加依赖

在build.gradle(module:app)的dependencies块内,添加

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

2. 新建ViewModel的拓展类

class GameViewModel : ViewModel() {
...
}

3. 在片段(UI控制器)中添加ViewModel的引用

private lateinit var viewModel: GameViewModel

4. 初始化ViewModel

在配置更改(例如屏幕旋转)期间,将重新创建UI控制器(例如片段)。但是,ViewModel实例仍然存在。如果ViewModel使用ViewModel该类创建实例,则每次重新创建片段时都会创建一个新对象。所以使用ViewModelProvider来创建ViewModel实例。它会保证单例。

viewModel = ViewModelProvider(this).get(GameViewModel::class.java)

5. 在UI控制器中使用

经过以上设置,即可在UI控制器中调用ViewModel的方法来操纵数据,需要数据的地方直接访问ViewModel即可。


传入参数的使用

1. 1. 添加依赖

在build.gradle(module:app)的dependencies块内,添加

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

2. 新建ViewModel的拓展类

注意其有构造函数有参数

class ScoreViewModel(finalScore: Int) : ViewModel() {
    var score = finalScore
    ...
}

3. 新建一个实现ViewModelProvider.Factory接口的类。

它是工厂类,给它构造函数添加一个参数(与前一步对应)

class ScoreViewModelFactory(private val finalScore: Int) : ViewModelProvider.Factory {
}

4. 添加上一步的具体实现

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相关变量

private lateinit var viewModel: ScoreViewModel
private lateinit var viewModelFactory: ScoreViewModelFactory

6. 初始化viewModel工厂变量

其中的ScoreFragmentArgs 是自动生成的类。如果当前UI控制器有参数,就会生成这样一个Args类

viewModelFactory = ScoreViewModelFactory(ScoreFragmentArgs.fromBundle(arguments!!).score)

7. 使用工厂类构建viewModel变量

viewModel = ViewModelProvider(this, viewModelFactory).get(ScoreViewModel::class.java)

8. 在UI控制器中使用

经过以上设置,即可在UI控制器中调用ViewModel的方法来操纵数据,需要数据的地方直接访问ViewModel即可。

最后修改:2020 年 06 月 03 日
如果觉得我的文章对你有用,请随意赞赏