安卓MVVM多API调用

问题描述 投票:0回答:1

我正在做一个MVVM的例子项目,没有复杂的注入依赖库和RX(因为我认为没有这些非常有效的东西,人们更好地理解它是如何从根本上工作的),但它更难做:)

我遇到了麻烦,我在这里使用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>?

){

}

呼叫进入 品种活动 :

  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 "的值在最后一项上。

有我 品种查看模型 :

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
        }
    }

}

并完成 猫咪资源库 方法来获取图片。


    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,提前感谢您的时间。

android kotlin mvvm android-architecture-components
1个回答
0
投票

似乎你不应该分别获取数据,而应该同时获取数据,并将结果合并为一个响应。

一般来说。

  1. 移除 getBreedImagesFromApi.
  2. 更新您的 getBreedsFromApi (我想这是存在的,而且你使用的是 coroutines)在你已经有的获取品种的调用中获取这两个数据。你可以使用 async 和 await() 以此向两个不同的端点发出两个请求,让它们同时运行,并等待两个请求完成。
  3. 删除 "foreach",因为当你得到品种列表时,图像已经存在了。

希望这能帮到你!


0
投票

我想视图应该从你的视图模型中接收一个完成的对象数据,这意味着你必须在视图模型中完成所有这些逻辑。

  1. 点击这两个API,然后在视图模型中观察它们。
  2. 再创建一个Live Data,负责将数据传递给你的View(ActivityFragment)。
  3. 更新两个API观察者的ViewLiveData。

而要做到这一点,你将需要 TransformationMediatorLiveData 在你的view-model中,你可以使用Rxjava。

你也可以使用Rxjava,检查 逐条取货

© www.soinside.com 2019 - 2024. All rights reserved.