Jetpack从入门到几乎入门(三)

514 阅读2分钟

Jetpack从入门到几乎入门(三)

我正在参加「掘金·启航计划」

前言

Jetpack系列:

Jetpack从入门到几乎入门(一) - 掘金 (juejin.cn)

Jetpack从入门到几乎入门(二) - 掘金 (juejin.cn)

Jetpack从入门到几乎入门(三) - 掘金 (juejin.cn)

本文是对Jetpack中LiveData的使用的拓展,将介绍LiveData的几个进阶用法

进阶:map() 和switchMap()

LiveData 为了能够应对各种不同的需求场景,提供了两种转换方法:map()switchMap()方法,下面我们来学习两种方法的用法和使用场景

map

map方法的作用是将实际包含数据的LiveData 和仅用于观察数据的LiveData 进行转换。

现在有一个场景:我们通过网络请求,获得了一个User类数据(LiveData),这个数据中包含了姓名和年龄信息,但是,我们只想把User.name暴露给外部观察者而不关心年龄。此时我们就可以通过map来将User类型的LiveData 转型成任意其他类型的LiveData,从而来实现上述场景。

具体用法:

  • ViewModel

    class MainViewModel(countReserved: Int) : ViewModel() { 
        val userLiveData = MutableLiveData<User>() 
        val userName: LiveData<String> = Transformations.map(userLiveData)
        { user -> "${user.firstName} ${user.lastName}" }
        ... 
    }
    

    我们可以看到,map()方法接收两个参数:

    • 第一个参数是原始的LiveData 对象
    • 第二个参数是一个转换函数,我们可以在此处实现LiveData 转型的代码

这就是map()方法的使用。

switchMap()

switchMap可以根据传入的LiveData的值去切换或创建新的LiveData,当ViewModel 中的某个LiveData 对象是通过调用另外的方法获取的时(比如我们有些数据需要依赖其他数据进行查询),我们可以使用switchMap()方法

现在有一个场景:有一个学生类,里面包含多门科目的成就数据,但是我们的UI只需要我们展现一门课的成绩,我们需要判断哪门课程成绩该展现

此段代码参考自学会使用LiveData和ViewModel,我相信会让你在写业务时变得轻松🌞

data class Student (var englishScore: Double, var mathScore: Double, val scoreTAG: Boolean)
class SMViewModel: ViewModel() {
    private var studentLiveData = MutableLiveData<Student>()
    val transformationsLiveData = Transformations.switchMap(studentLiveData) {
        if (it.scoreTAG) {
            MutableLiveData(it.englishScore)
        } else {
        MutableLiveData(it.mathScore)
        }
    }
}

我们定义了studentLiveData用来观察LiveData的变化,主要是观察scoreTAG的值。

switchMap()方法同样接收两个参数:

  • 第一个参数传入我们新增的studentLiveData
  • 第二个参数是一个转换函数,我们再次编写转换逻辑

使用时:

var student = Student()
person.englishScore = 88.2
person.mathScore = 91.3
//判断显示哪个成绩
person.condition = true
switchMapViewModel.conditionLiveData.postValue(person)

studentLiveData变动时,观察它的switchMap()就会执行,然后调用我们写好的转换函数得到我们真正想要的LiveData,这样我们就实现了通过一个LiveData数据查询另一个数据。