Android Kotlin Jetpack之LiveData

作者: 水天滑稽天照八野滑稽石 | 来源:发表于2019-08-25 22:52 被阅读1次

    前言

    这次我们来聊下LiveData,众所周知,Android里面实现MVVM的方式有2中,一种就是DataBinding,这种方式可以节省一部分通知UI更新的代码,但是布局就不能复用了,另外一种就是我们现在说提到的LiveDate

    导入

    首先我们要依赖Google仓库,在project -> build.gradle里

    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    

    然后是Module -> build.gradle

        def lifecycle_version = "2.0.0"
        implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    

    概况

    LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware,(LiveData是一个可观察的数据持有者类。与常规observable不同,LiveData是生命周期感知的。)

    我对LiveData的理解就是:这个一个跟EventBus很类似的东西,任意地方发布事件(liveData改变),我订阅这个事件的能接受到事件(接收到LiveData的改变),但LiveData是生命周期感知的:
    1.如果当前的LifecycleOwner不处于活动状态(例如onPasue()、onStop())时,LiveData是不会回调observe()的
    2.LiveData没有如果被observe(),此时你调用这个LiveData的postValue(...)/value=...,同样不会被回调

    使用

    class MyViewModel : ViewModel(){
        /**
         *  这里通过懒加载的方式new了一个MutableLiveData对象
         *  LiveDate是一个抽象类,MutableLiveData是它的实现类
         *  它们之间的关系类似于List和ArrayList
         *  这里的 name 说白了就是一个个 LiveData类型的String
         *  我们只是借助LiveData的特性,本质上还是String
         *  @sample MutableLiveData<List<String>>()
         *  @sample MutableLiveData<Int>()
         *  @sample MutableLiveData<类名>()
         */
        val name: MutableLiveData<String> by lazy {
            MutableLiveData<String>()
        }
    }
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            var model = ViewModelProviders.of(this)[MyViewModel::class.java]
            // 这个this是LifecycleOwner
            model.name.observe(this, Observer {
                text.text = it
            })
            // 更新被观察者数据,LiveData会通知观察者
            model.name.value = "xiao"
        }
    
        //或者在具体的业务类使用postValue更新数据
        fun modelTest(){
            var model = MutableLiveData<String>()
            model.postValue("xiao")
        }
    }
    

    不同的liveData实现类

    liveData是一个抽象类,系统实现了2个类,MutableLiveDataMediatorLiveData
    MutableLiveData前面已经说过了并展示了怎么用,下面就来说下MediatorLiveData

    MediatorLiveData

    MutableLiveData的子类,一个更强大的LiveData,它允许我们合并多个 LiveData,任何一个 LiveData 有更新就会发送通知。比如我们的数据来源有两个,一个数据库一个网络,这时我们就有2个 LiveData了,然后我们可以使用 MediatorLiveData 来 merge 这两个 LiveData

    class MyViewModel : ViewModel(){
        /**
         *  场景假设:
         *  couldModel是从服务据请求回来的数据
         *  dataModel是数据库请求回来的数据
         *  model是用来UI展示的数据
         *  如果网络请求还没回来就展示先展示数据库的数据
         */
        val couldModel = MutableLiveData<String>()
        val dataModel = MutableLiveData<String>()
        val model = MediatorLiveData<String>()
    }
    
    class MainActivity : AppCompatActivity() {
    
        private lateinit var myModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            myModel = ViewModelProviders.of(this)[MyViewModel::class.java]
            initLiveData()
            button1.setOnClickListener {
                //场景模拟,优先返回dataModel数据,随后延迟2S返回coludModel数据
                myModel.dataModel.value = "data"
                Handler().postDelayed({
                    myModel.couldModel.value = "cloud"
                },2000)
            }
        }
    
        //统一处理2个的LiveData
        private fun initLiveData(){
            myModel.apply {
                //通过addSource来merge 多个liveData
                model.addSource(dataModel, Observer {
                    model.value = it
                })
    
                model.addSource(couldModel){
                    model.value = it
                }
    
                //数据变化就更新UI
                model.observe(this@MainActivity, Observer {
                    text.text = it
                })
            }
        }
    }
    

    map

    如果是用过RxJava的小伙伴,对这个操作符肯定不陌生(Kotlin也有哟~),这个操作符的作用是转换,就是我输入一个数据A,我再转成数据B输出

    class MyViewModel : ViewModel(){
        val name = MutableLiveData<String>()
        val mapName = Transformations.map(name){
            //在前面增加"map"字符串,也可以做更复杂的工作,如去查数据库并返回
            "map$it"
        }
    }
    
    class MainActivity : AppCompatActivity() 
        private lateinit var myModel: MyViewModel
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            myModel = ViewModelProviders.of(this)[MyViewModel::class.java]
            myModel.mapName.observe(this, Observer {
                text.text = it
            })
            myModel.name.postValue("xiao")
        }
    }
    

    switchMap

    switchMap的用法和map基本雷同,差异在于返回值不同

       val mapName: LiveData<String> = Transformations.map(name){ }//返回值是LiveData<String>类型
       val switchMap: LiveData<String> = Transformations.switchMap(name){ }//返回值是LiveData<*> 
    

    小结

    以上便是LiveData的用法了,说实话内容没我想象中的多...其实LiveData更多还是要配合其他Jetpack组件使用,ORM数据库Room和分页加载Paging,之后我们继续再说

    相关文章

      网友评论

        本文标题:Android Kotlin Jetpack之LiveData

        本文链接:https://www.haomeiwen.com/subject/htgjsctx.html