前言
VM是什么?VM指的就是ViewModel,它是MVVM的核心,相当于MVC的C层或MVP的P层。
为什么要使用MVVM?VM拥有自己的生命周期,不需要再去写监听生命周期的变化代码,,配合上DataBinding和LiveData能够实现一个比较现代的架构,可以实现数据驱动UI。
VM解决了什么痛点?相比于MVP的Presenter,ViewModel能够监听生命周期的变化。相比于onSaveInstanceState()中保存数据和Oncreate()中恢复数据,ViewModel保存的数据量更大,并且能够保存非序列化的对象。它更容易的从UI控制中将逻辑分离出来,去监听控制一些逻辑并及时清理它们避免内存泄漏。
1 如何使用ViewModel
首先我们需要继承ViewModel,如下所示:
class MyViewModel : ViewModel() {
private val users: MutableLiveData<List<User>> by lazy {
MutableLiveData().also {
loadUsers()
}
}
fun getUsers(): LiveData<List<User>> {
return users
}
private fun loadUsers() {
// Do an asynchronous operation to fetch users.
}
override fun onCleared() {
super.onCleared()
}
}
然后在Activity中使用ViewModelProviders获取ViewModel。
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
val model = ViewModelProviders.of(this)[MyViewModel::class.java]
model.getUsers().observe(this, Observer<List<User>>{ users ->
// update UI
})
}
}
如果重新创建Activity只会使用第一次创建的MyViewModel实例,因此当所属的Activity结束你可以使用onCleared()去清理数据。
2 ViewModel的生命周期
通常我们会在Oncreate中创建ViewModel,此时ViewModel就会伴随该Activity一整个生命周期,直至结束。
viewmodel生命周期
3 使用ViewModel共享数据
使用ViewModel+LiveData可以更加灵活的实现事件的传递,MasterFragment点击,DetailFragment响应。相比于传统的事件总线或者别的消息共享方式,Activity可以不用去理会他们时如何通信的,Fragment之间也不会相互干扰,因为LiveData已经能很好的做到这些事了。如下所示:
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")
model.selected.observe(this, Observer<Item> { item ->
// Update the UI
})
}
}
当使用ViewModelProviders.of(this)
实例化两个对象时,如果传入的对象是同一个Activity,获取的实际上是同一个ViewModel。
4 使用ViewModel加载数据
你可以使用ViewModel和一些类去做数据加载,我最近就使用到ViewModel+Room+LiveData+Paging+SharePrefrence去存储一些数据。对于如何在ViewModel中加载数据我就不在这里多说了。毕竟怕弄混乱了。。。
总结
完成一个MVVM架构,你可以用DataBinding、ViewModel、Room、Paging、LiveData。可以自动监听数据的变化,少做很多不必要的操作。
网友评论