前言
之前的文章中我们了解了Jetpack组件中ViewModel,LiveData与Lifecycle,在工作中,我已经明明白白的知道了他们的作用,我现在写的每个页面几乎都少不了它们,当然,这也就避免不了我继续深入下去的心,于是我在官网又发现了Jetpack组件LiveData的两个好伙伴-map与switchMap。
可惜官网不够人性化,这部分的中文资料还是没有完善,不过我已经花费一段时间去阅读,下面就让我们看看它们庐山真面目。
正篇
出现背景与使用场景
在公司开发,大多数时候的项目还是比较复杂的,于是就会出现很多特殊的需求,而且代码也会讲究许多,也就是这个原因,LiveData为了去适应各种不同的需求场景,出现了两种转换方法:map()和switchMap()。 首先,让我们看看map():
map()方法的使用
使用方法的说明,我们就先举一个例子,假设你有了一个用户类Uer类,这个类包含用户姓名与年龄:
data class User(var firstName : String, var lastName : String, var age : Int)
于是我们可以在ViewModel中创建一个相应的LiveData去包含User类型数据:
class MainViewModel(countReserved: Int) : ViewModel() { val userLiveData = MutableLiveData<User>() ... }
这时就有问题了,如果在Activity中这就会将整个User类型的LiveData暴露给外部,需求要是说年龄是隐私,不能泄露,我们明确只要用户姓名,这种情形下就是非常糟糕的了,而map()方法就是解决这个问题的:
class MainViewModel(countReserved: Int) : ViewModel() { private val userLiveData = MutableLiveData<User>() val userName : LiveData<String> = Transformations.map(userLiveData) { user -> "${user.firstName} ${user.lastName}" } ... }
这里代码说明了map()方法的作用就是将实际包含数据的LiveData和仅用于观察数据的LiveData进行转换。
上面的代码中需要用户的名称,于是我们调用了Transformations的map()方法去对LiveData数据类型进行转换,这个方法接受了两个参数,第一个是原始LiveData对象,第二个则是转换函数;
而我们需要在转换函数里编写具体的转换逻辑,而上述代码中转换逻辑也是十分简单的,即将User对象转换称一个只包含用户名称的字符串。
此外,为了保证数据的封装性,我们将userLiveData声明成private,这样在外部使用只要观察userName这个LiveData即可。
而当userLiveData数据发生变化时,map()方法会监听到变化而去执行转换函数中的逻辑,接着再将转换之后的数据告知userName观察者。
这样一套下来,我们的map()的工作就完成了,为了防止因为Konltin表达过于简单,导致我们认为转换逻辑方法比较难,我们再看看Java的写法:
源码也是十分清晰的:
仅仅就是返回你想要的类型即可。
结语
现在我们对map()方法有了一定的认知了,接下来,我们会去探究switchMap()方法,然后将二者结合使用再应用到我们的实例上演示一番,感谢您的观看!