Попробуйте поймать с помощью Livedata

#android #kotlin #android-livedata

Вопрос:

У меня есть приложение, которое отображает список фильмов. Существует несколько типов(боевик,комедия,тренды и т.д.), А также функция поиска.

Я сохраняю результаты поиска в переменной с помощью switchmap. Я использую try и catch, чтобы знать, что отображать.

Тем не менее, у меня возникли проблемы с использованием переменной результатов поиска в try and catch, в частности, ошибка «Не удается присвоить «значение»: сеттер является общедоступным в «getMovies»»

Ниже приведена модель представления.

Любая помощь будет признательна.

movieslistviewмодель.кт

 package com.example.moviesapp.ui

import androidx.lifecycle.*
import com.example.moviesapp.data.MoviesResults
import com.example.moviesapp.data.remote.MoviesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

const val DEFAULT_QUERY = " "

//Enum class for network state
enum class MovieApiStatus { LOADING, ERROR, DONE }


@HiltViewModel
class MoviesListViewModel @Inject constructor(
    private val repository: MoviesRepository,
) : ViewModel() {


    private var currentQuery = MutableLiveData(DEFAULT_QUERY)

    private val _moviesAction = MutableLiveData<List<MoviesResults.Movies>>()
    val moviesAction: LiveData<List<MoviesResults.Movies>> = _moviesAction

    private val _moviesComedy = MutableLiveData<List<MoviesResults.Movies>>()
    val moviesComedy: LiveData<List<MoviesResults.Movies>> = _moviesComedy

    private val _moviesHorror = MutableLiveData<List<MoviesResults.Movies>>()
    val moviesHorror: LiveData<List<MoviesResults.Movies>> = _moviesHorror

    private val _moviesRomance = MutableLiveData<List<MoviesResults.Movies>>()
    val moviesRomance: LiveData<List<MoviesResults.Movies>> = _moviesRomance

    private val _moviesScifi = MutableLiveData<List<MoviesResults.Movies>>()
    val moviesScifi: LiveData<List<MoviesResults.Movies>> = _moviesScifi

    private val _moviesTrending = MutableLiveData<List<MoviesResults.Movies>>()
    val moviesTrending: LiveData<List<MoviesResults.Movies>> = _moviesTrending

    private val _networkState = MutableLiveData<MovieApiStatus>()
    val networkState: LiveData<MovieApiStatus> = _networkState

    init {
        getMovies()
    }


    var movies = currentQuery.switchMap { queryString ->
        liveData {
            emit(repository.getSearchResults(queryString))
        }
    }



    fun searchMovies(query: String) {

        currentQuery.value = query

    }

    private fun getMovies() {
        viewModelScope.launch {
            _networkState.value = MovieApiStatus.LOADING
            try {
                _networkState.value = MovieApiStatus.DONE
                _moviesAction.value = repository.getActionMovies()
                _moviesComedy.value = repository.getComedyMovies()
                _moviesHorror.value = repository.getHorrorMovies()
                _moviesRomance.value = repository.getRomanceMovies()
                _moviesScifi.value = repository.getScifiMovies()
                _moviesTrending.value = repository.getTrendingMovies()



            } catch (e: Exception) {
                _networkState.value = MovieApiStatus.ERROR
                _moviesAction.value = listOf()
                _moviesComedy.value = listOf()
                _moviesHorror.value = listOf()
                _moviesScifi.value = listOf()
                _moviesRomance.value = listOf()
                _moviesTrending.value = listOf()
                movies.value = listOf()


            }

        }

    }


    class MoviesListViewModelFactory @Inject constructor(private val repository: MoviesRepository) :
        ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(MoviesListViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return MoviesListViewModel(repository) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")

        }


    }


}





 

Ответ №1:

movies имеет тип LiveData<T> , так как вы используете Transformations.switchMap (<a rel=»noreferrer noopener nofollow» href=»https://developer.android.com/reference/androidx/lifecycle/Transformations#switchMap(androidx.lifecycle.LiveData, androidx.arch.core.util.Function<X, androidx.lifecycle.LiveData>)» rel=»nofollow noreferrer»>здесь документация). Вы можете использовать MediatorLiveData для передачи из двух разных источников

Комментарии:

1. Значит, фильмы будут иметь тип mediatorlivedata?