Android MVVM множественный вызов API - PullRequest
0 голосов
/ 25 апреля 2020

Я собираюсь сделать пример проекта 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>?

){

}

вызов в 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, он очень грязный (а также это не ' не работает, потому что не беги на Сэма В этот момент, когда я устанавливаю изображения в обозревателе, значение «оно» находится на последнем элементе

, это мой 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
        }
    }

}

и до конечной sh метод 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, Заранее спасибо за ваше время.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Я полагаю, что представление должно получить законченные данные объекта от вашей модели представления, что означает, что вы должны делать все эти логи c в модели представления. в view-model.

создайте еще одну Live Data, ответственную за передачу данных вашему View (Activity / Fragment) , обновите ViewLiveData от обоих наблюдателей API.

и для этого вам понадобится Transformation или MediatorLiveData в вашей модели представления.

также вы можете использовать Rx java, отметьте получить каждый элемент в списке

0 голосов
/ 26 апреля 2020

Похоже, вместо того, чтобы извлекать данные отдельно, вы должны извлекать их одновременно и объединять результат в один ответ.

Вообще говоря:

  1. Удалить getBreedImagesFromApi.
  2. Обновите ваш getBreedsFromApi (я полагаю, что он существует, и вы используете сопрограммы), чтобы получить обе части данных в одном вызове, который у вас уже есть для получения пород. Вы можете использовать asyn c и await () для этого, чтобы запустить два запроса к двум различным конечным точкам, запустить их одновременно и дождаться окончания обоих запросов sh.
  3. Удалите «foreach», потому что к тому времени, когда вы получите список пород, изображения будут существовать.

Надеюсь, это поможет!

...