MVVM(二) ViewModel的使用

前言

VM是什么?VM指的就是ViewModel,它是MVVM的核心,相当于MVC的C层或MVP的P层。
为什么要使用MVVM?VM拥有自己的生命周期,不需要再去写监听生命周期的变化代码,,配合上DataBinding和LiveData能够实现一个比较现代的架构,可以实现数据驱动UI。
VM解决了什么痛点?相比于MVP的Presenter,ViewModel能够监听生命周期的变化。相比于onSaveInstanceState()中保存数据和Oncreate()中恢复数据,ViewModel保存的数据量更大,并且能够保存非序列化的对象。它更容易的从UI控制中将逻辑分离出来,去监听控制一些逻辑并及时清理它们避免内存泄漏。

相关文章阅读
MVVM(一) DataBinding的使用
MVVM(三) 如和实现MVVM?


1 如何使用ViewModel

 首先我们需要继承ViewModel,如下所示:

class MyViewModel : ViewModel() {
    private val users: MutableLiveData> by lazy {
        MutableLiveData().also {
            loadUsers()
        }
    }

    fun getUsers(): LiveData> {
        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>{ 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()

    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 ->
            // Update the UI
        })
    }
}

 当使用ViewModelProviders.of(this)实例化两个对象时,如果传入的对象是同一个Activity,获取的实际上是同一个ViewModel。


4 使用ViewModel加载数据

 你可以使用ViewModel和一些类去做数据加载,我最近就使用到ViewModel+Room+LiveData+Paging+SharePrefrence去存储一些数据。对于如何在ViewModel中加载数据我就不在这里多说了。毕竟怕弄混乱了。。。


总结

 完成一个MVVM架构,你可以用DataBinding、ViewModel、Room、Paging、LiveData。可以自动监听数据的变化,少做很多不必要的操作。

你可能感兴趣的:(MVVM(二) ViewModel的使用)