Я впервые использую Rx Java и PagedList. Я следовал руководству Риада, как оно объяснительно (Android Mov ie Приложение MVVM). Единственное отличие состоит в том, что мне пришлось создать свою фабрику моделей представления иначе, поскольку ViewModelProviders.of()
, который он использовал, устарел.
Основная проблема заключается в том, что я вижу, что ответ от Api собирается, но не доходит до мой репозиторий и viewmodel. Я попытался отладить и найти причину, по которой это происходит, но не смог понять.
Возможно, что-то не хватает, что я мог бы помочь с
Источником данных
class MovieDataSource(private val apiService:TheMovieDbInterface, private val compositeDisposable: CompositeDisposable):PageKeyedDataSource<Int, Movies>() {
var page = FIRST_PAGE
val networkState = MutableLiveData<NetworkState>()
override fun loadInitial(
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, Movies>
) {
networkState.postValue(NetworkState.LOADING)
try {
compositeDisposable.add(
apiService.getPopularMovies(page)
.subscribeOn(Schedulers.io())
.subscribe({it->
callback.onResult(it.results, null, page+1)
Log.i("MovieDetailsResponse", "${it.results}")
networkState.postValue(NetworkState.LOADED)
},{
networkState.postValue(NetworkState.ERROR)
Log.e("MovieDetailsResponse", it.message)
})
)
}
catch (e:Exception){
Log.e("MovieDetailsResponse", e.message)
}
}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Movies>) {
networkState.postValue(NetworkState.LOADING)
try {
compositeDisposable.add(
apiService.getPopularMovies(params.key)
.subscribeOn(Schedulers.io())
.subscribe({it->
if(it.totalPages >= params.key){
callback.onResult(it.results, params.key+1)
networkState.postValue(NetworkState.LOADED)
}
else{
networkState.postValue(NetworkState.END_OF_LIST)
}
},{
networkState.postValue(NetworkState.ERROR)
Log.e("MovieDetailsResponse", it.message)
})
)
}
catch (e:Exception){
Log.e("MovieDetailsResponse", e.message)
}
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Movies>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
DataSourceFactory
class MovieDataSourceFactory(private val apiService: TheMovieDbInterface, private val compositeDisposable: CompositeDisposable):DataSource.Factory<Int, Movies>() {
val movieLiveDataSource = MutableLiveData<MovieDataSource>()
override fun create(): DataSource<Int, Movies> {
val movieDataSource = MovieDataSource(apiService, compositeDisposable)
movieLiveDataSource.postValue(movieDataSource)
return movieDataSource
}
}
PagedListRepository
lass MoviePagedListRepository(private val apiService:TheMovieDbInterface) {
lateinit var moviePagedList:LiveData<PagedList<Movies>>
lateinit var movieDataSourceFactory: MovieDataSourceFactory
fun fetchLiveMoviePagedList(compositeDisposable: CompositeDisposable):LiveData<PagedList<Movies>>{
movieDataSourceFactory = MovieDataSourceFactory(apiService, compositeDisposable)
val config = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPageSize(POST_PER_PAGE)
.build()
moviePagedList = LivePagedListBuilder(movieDataSourceFactory, config).build()
Log.i("moviePagedList", "$moviePagedList")
return moviePagedList
}
fun getNetworkState():LiveData<NetworkState>{
return Transformations.switchMap<MovieDataSource, NetworkState>(
movieDataSourceFactory.movieLiveDataSource, MovieDataSource::networkState
)
}
}
ViewModel
class MainViewModel(private val movieRepository:MoviePagedListRepository): ViewModel() {
private val compositeDisposable = CompositeDisposable()
val moviePagedList : LiveData<PagedList<Movies>> = movieRepository.fetchLiveMoviePagedList(compositeDisposable)
val networkState:LiveData<NetworkState> by lazy {
movieRepository.getNetworkState()
}
fun isListEmpty():Boolean{
return moviePagedList.value?.isEmpty()?: true
}
override fun onCleared() {
super.onCleared()
compositeDisposable.dispose()
}
}