【发布时间】:2020-04-25 18:50:45
【问题描述】:
我正在制作一个没有注入依赖库和 RX 复杂性的 MVVM 示例项目(因为我认为对于没有所有这些非常高效的东西的人来说,最好了解它是如何从根本上工作的)但它更难制作:)
我遇到了麻烦,我在这里使用 CatApi:https://thecatapi.com/ 我正在尝试做一个微调器,其中包含品种名称以及左侧的猫图片(对于每个品种),但在此 API 中,您只能通过两次调用获得此结果(一个用于品种,一个用于图像)品种),我不会将 API 的研究推得太远,因为即使 API 可以解决我的问题,我也想面对这个问题,因为它可能在我以后的生活中发生:)
所以我的问题是我做了以下代码:
BreedEntity:
package com.example.mvvm_kitty.data.local.entities
//Entity was used to be stored into a local DB so no use here
data class BreedEntity (
val adaptability: Int,
val affection_level: Int,
val description: String,
val id: String,
var name: String,
val life_span: String,
val origin: String,
var iconImage : BreedImageEntity?,
var images: List<BreedImageEntity>?
){
}
调用BreedActivity:
private fun subscribeToModel(breedsViewModel: BreedsViewModel) {
//Todo: Gerer les erreurs reseau
breedsViewModel.getBreeds().observe(this, Observer {
breedEntities ->
mBinding.catSelected = breedEntities[0]
breedSpinnerAdapter = BreedsSpinnerAdapter(this, breedEntities)
mBinding.breedSelector.adapter = breedSpinnerAdapter
breedEntities.forEach {breedEntity ->
breedsViewModel.getBreedImages(breedEntities.indexOf(breedEntity)).observe(this, Observer {
breedEntity.iconImage = it[0]
})
}
})
}
是的,我认为 foreach 很脏(而且它不起作用,因为不要同时运行,所以当我在观察者中设置图像时,“it”值在最后一项上
这是我的BreedsViewModel:
package com.example.mvvm_kitty.viewmodels
import android.app.Application
import android.util.Log
import android.view.animation.Transformation
import androidx.lifecycle.*
import com.example.mvvm_kitty.BasicApp
import com.example.mvvm_kitty.data.local.entities.BreedEntity
import com.example.mvvm_kitty.data.local.entities.BreedImageEntity
import com.example.mvvm_kitty.data.repositories.CatRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
class BreedsViewModel(application: Application, private val catRepository: CatRepository) : AndroidViewModel(application) {
private val mObservableBreeds: LiveData<List<BreedEntity>> = catRepository.getBreeds()
/**
* Expose the product to allow the UI to observe it
*/
fun getBreeds(): LiveData<List<BreedEntity>> {
return mObservableBreeds
}
fun getBreedImages(index : Int): LiveData<List<BreedImageEntity>> {
val breed = mObservableBreeds.value?.get(index)
return catRepository.getBreedImages(breed!!.id)
}
/**
* Factory is used to inject dynamically all dependency to the viewModel like reposiroty, or id
* or whatever
*/
class Factory(private val mApplication: Application) :
ViewModelProvider.NewInstanceFactory() {
private val mRepository: CatRepository = (mApplication as BasicApp).getCatRepository()
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return BreedsViewModel(mApplication, mRepository) as T
}
}
}
并完成 CatRepository 方法以获取图像:
private fun getBreedImagesFromApi(id: String) : LiveData<List<BreedImageEntity>>{
mObservableBreedImages.addSource(catService.getAllImages(id, 10)){
mObservableBreedImages.postValue(it.resource?.map { breedDto ->
breedDto.toEntity()})
}
return mObservableBreedImages
}
我的问题是如何以干净的方式获取每个项目的图像(因为我认为我的代码很好但 foreach 观察者部分很脏)
如果有人可以帮助我,那就太好了:D,提前感谢您的时间。
【问题讨论】:
-
几乎可以肯定 switchMap 转换会有所帮助。不过,我现在没有时间写一个例子。在这里查看developer.android.com/reference/android/arch/lifecycle/… 应该类似于 Transformations.switchMap(catRepository.getBreeds) { // 这里调用方法来获取每个品种的图像并使用图像创建 Breeds 实体 }
-
不要使用嵌套的观察者,使用
Transformations.switchMap
标签: android kotlin mvvm android-architecture-components