Jetpack LiveData使用(一)简要介绍了liveData最简单的使用方式。
下面我们看看livedata的数据格式转换map、livedata多源监听MediatorLiveData 、livedata多源切换和控制SwitchMap的使用。
一、数据转化map由于数据的来源多样,赋值于UI需要将原始数据转换为UI对应的数据类型或者数据bean,此时可以使用map:
原始代码仍然基于,这里只需添加变化的map操作,
activity的map:
//map转换后的数值:
val liveMappedData = liveAppleData.map {
Pair(it.hashCode(), it)
}
liveMappedData.observe(this, Observer {
tv_mapped_data_activity.text = "map 后的值:${it}"
Log.i("LiveActivity", "LiveData在LiveActivity中 map 后 $it")
})
fragment的map:
//map换后的数值:
val liveMapApple = liveAppleData.map {
Log.d("AppleFragment", "LiveData在AppleFragment中 map $it")
"it mapped it ${it.takeLast(4)}"
}
liveMapApple.observe(viewLifecycleOwner, Observer {
val s = "mapped 后的值: $it"
tv_mapped_live_apple.setText(s)
Log.w("AppleFragment", "LiveData在AppleFragment中 map后的数据 $it")
})
可以看到activity中map将原始值映射为了一个键值对,key为hashcode,value为原始值;
而fragment中map后的值为当前的值的后四位。
二、MediatorLiveData
中介者,媒介,监听多个数据源liveData的数据,进行统一响应处理:
mediator的liveData可以监听A,B两个数据源的变化,通过addSource后,并响应A/B的变化,转化为mediator的变化。
为了演示多个数据源,我们再加两个liveData的实例:
//中介者MediatorLiveData使用演示:
val liveOne = MutableLiveData()
val liveTwo = MutableLiveData()
val mediatorLive = MediatorLiveData()
在activity中添加两个按钮,每次点击按钮都会产生新数据,这里把新数据源的观察对象设置到了mediatorLive中:
//中介者MediatorLiveData使用演示:
btn_change1_live.setOnClickListener {
liveOne.value = "one:${System.currentTimeMillis().toString().takeLast(6)}"
}
btn_change2_live.setOnClickListener {
liveTwo.value = "two:${System.currentTimeMillis().toString().takeLast(6)}"
}
mediatorLive.addSource(liveTwo) {
Log.d("LiveActivity", "LiveActivity中 LiveTwo ---> $it")
mediatorLive.value = "two >>>>>" to it
}
mediatorLive.addSource(liveOne) {
Log.d("LiveActivity", "LiveActivity中 LiveOne ---> $it")
mediatorLive.value = "one >>" to it
}
mediatorLive.observe(this, Observer {
Log.w("LiveActivity", "LiveActivity中 mediatorLive ---> $it")
})
在fragment中可以将监听到的变化数据源更新到UI上:
//中介者MediatorLiveData使用演示:
mediatorLive.observe(viewLifecycleOwner, Observer {
//如果在inactive状态下,one two都变化了,它resume后只接受 代码顺序 最新添加的 source 的最后的值
val s = "mediator it $it"
tv_media_live_apple.setText(s)
Log.w("AppleFragment", "AppleFragment中 mediatorLive ---> $it")
})
点击两个按钮后,在fragment中均能响应,变化为对应的数据源的数值:
三、SwitchMap
用于数据源的转化,多数据源的切换和控制,配合mediator的liveData使用,根据条件,选择数据源
这里需和map区分下,map是对livedata内部的数据进行的转化操作;
SwitchMap则返回的仍然是livedata数据源,只是对多个数据源进行的选择,例如多个数据源过来,但是我们只选用符合某一条件的数据源
在二的基础上添加如下代码:
//switch map 结合mediator,通过条件,控制选择数据源,这里模拟的是,it的数字奇偶,控制最终输出
val swLive = mediatorLive.switchMap {
if (it.second.takeLast(1).toInt() % 2 == 0) liveOne else liveTwo
}
//UI可以看出,不论是one,还是 two,改变的话,只有满足条件,才会生效。
swLive.observe(viewLifecycleOwner, Observer {
tv_switch_live_apple.text = it
Log.w("AppleFragment", "AppleFragment中 switchMap ---> $it")
})
添加后可以自己添加过滤条件,例如本例的条件就是数据源是奇数时使用liveTwo,是偶数时使用liveOne的数据源,通过条件,控制选择数据源。
完整项目代码