LiveData
可以通过Transformations
的map和switchMap操作,将一个LiveData转成另一种类型的LiveData,效果与RxJava的map/switchMap操作符类似。可以看看两个函数的声明
public static <X, Y> LiveData map(
@NonNull LiveData source,
@NonNull final Function<X, Y> mapFunction)
public static <X, Y> LiveData switchMap(
@NonNull LiveData source,
@NonNull final Function<X, LiveData> switchMapFunction)
根据以上代码,我们可以知道,对应的变换函数返回的类型是不一样的:map是基于泛型类型的变换,而switchMap则返回一个新的LiveData
。
还是以banner请求为例,我们将map和switchMap应用到实际场景中: 1: 为了能够手动控制请求,我们需要一个refreshTrigger
触发变量,当这个变量被设置为true时,通过switchMap生成一个新的LiveData
用作请求banner
private val refreshTrigger = MutableLiveData()
private val api = WanApi.get()
private val bannerLis:LiveData<ApiResponse<List>> = Transformations.switchMap(refreshTrigger) {
//当refreshTrigger的值被设置时,bannerList
api.bannerList()
}
2: 为了展示banner,我们通过map将ApiResponse
转换成最终关心的数据是List<BannerVO>
val banners: LiveData<List> = Transformations.map(bannerList) {
it.data ?: ArrayList()
}
LiveData与ViewModel结合
为了将LiveData
与Activity
解耦,我们通过ViewModel
来管理这些LiveData
。
class HomeVM : ViewModel() {
private val refreshTrigger = MutableLiveData()
private val api = WanApi.get()
private val bannerList: LiveData<ApiResponse<List>> = Transformations.switchMap(refreshTrigger) {
//当refreshTrigger的值被设置时,bannerList
api.bannerList()
}
val banners: LiveData<List> = Transformations.map(bannerList) {
it.data ?: ArrayList()
}
fun loadData() {
refreshTrigger.value = true
}
}
在activity_main.xml中加入banner布局,这里使用BGABanner-Android来显示图片
<?xml version="1.0" encoding="utf-8"?>
<cn.bingoogolapple.bgabanner.BGABanner
android:id=“@+id/banner”
android:layout_width=“match_parent”
android:layout_height=“120dp”
android:paddingLeft=“16dp”
android:paddingRight=“16dp”
app:banner_indicatorGravity=“bottom|right”
app:banner_isNumberIndicator=“true”
app:banner_pointContainerBackground=“#0000”
app:banner_transitionEffect=“zoom”/>
然后在MainActivity完成Banner初始化,通过监听ViewModel中的banners实现轮播图片的展示。
class MainActi