背景:通过Transformations.switchMap 实现实时变换影响其他变量值的API,实现牵一发而动全身的操作,不过由于其代码过于简洁,有必要分解一下帮助阅读。
项目地址:android-architecture-components
用户手动输入subredditName 关键字,repoResult跟随变化,然后通过repoResult的变化动态改变posts ,networkState ,refreshState 的功能实现,简化写法后通过Transformations静态导入switchMap,map,代码看起来非常简洁
//导包
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations.map
import androidx.lifecycle.Transformations.switchMap
import androidx.lifecycle.ViewModel
import com.android.example.paging.pagingwithnetwork.reddit.repository.RedditPostRepository
class SubRedditViewModel(private val repository: RedditPostRepository) : ViewModel() {
private val subredditName = MutableLiveData<String>()
private val repoResult = map(subredditName) {
repository.postsOfSubreddit(it, 30)
}
val posts = switchMap(repoResult, { it.pagedList })!!
val networkState = switchMap(repoResult, { it.networkState })!!
val refreshState = switchMap(repoResult, { it.refreshState })!!
}
还原代码:代码逻辑就很清晰了,当然也就相对不精简了
//导包
import androidx.arch.core.util.Function
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.paging.PagedList
import com.android.example.paging.pagingwithnetwork.reddit.repository.Listing
import com.android.example.paging.pagingwithnetwork.reddit.repository.NetworkState
import com.android.example.paging.pagingwithnetwork.reddit.repository.RedditPostRepository
import com.android.example.paging.pagingwithnetwork.reddit.vo.RedditPost
import kotlin.jvm.internal.Intrinsics
class SubRedditViewModel : ViewModel{
val networkState: LiveData<NetworkState>
val posts: LiveData<PagedList<RedditPost>>
val refreshState: LiveData<NetworkState>
val repository: RedditPostRepository
val subredditName: MutableLiveData<String>
val repoResult: LiveData<Listing<RedditPost>>
constructor(repository: RedditPostRepository) : super() {
this.repository = repository
this.subredditName = MutableLiveData<String>()
this.repoResult = Transformations.map(this.subredditName, object : Function<String, Listing<RedditPost>> {
override fun apply(input: String): Listing<RedditPost> {
return repository.postsOfSubreddit(input, 30)
}
})
Intrinsics.checkParameterIsNotNull(repository, "repository")
val switchMap = Transformations.switchMap(this.repoResult, object : Function<Listing<RedditPost>, LiveData<PagedList<RedditPost>>> {
override fun apply(input: Listing<RedditPost>?): LiveData<PagedList<RedditPost>>? {
return input?.pagedList
}
})
if (switchMap == null) {
Intrinsics.throwNpe()
}
this.posts = switchMap
val switchMap2 = Transformations.switchMap(this.repoResult, object : Function<Listing<RedditPost>, LiveData<NetworkState>> {
override fun apply(input: Listing<RedditPost>?): LiveData<NetworkState>? {
return input?.networkState
}
})
if (switchMap2 == null) {
Intrinsics.throwNpe()
}
this.networkState = switchMap2
val switchMap3 = Transformations.switchMap(this.repoResult, object : Function<Listing<RedditPost>, LiveData<NetworkState>> {
override fun apply(input: Listing<RedditPost>?): LiveData<NetworkState>? {
return input?.refreshState
}
})
if (switchMap3 == null) {
Intrinsics.throwNpe()
}
this.refreshState = switchMap3
}
}