LiveData <PagedList>не наблюдается в реализации библиотеки подкачки в Kotlin - PullRequest
0 голосов
/ 08 июня 2019

Недавно я начал играть вокруг kotlin. Я пытаюсь реализовать библиотеку подкачки для получения списка с сервера. Я полностью следую ниже статье для реализации того же самого. https://proandroiddev.com/mvvm-with-kotlin-android-architecture-components-dagger-2-retrofit-and-rxandroid-1a4ebb38c699

Код работает нормально для извлечения данных с сервера в DataSource, но по какой-то неизвестной причине не вызывается List Observe.

viewModel.ArticleList.observe () ... (эта часть не работает.)

Подробнее см. Ниже фрагменты кода реализации моего проекта.

package com.assessment.Articlebaseproject.repo.web.paging

import android.arch.lifecycle.MutableLiveData
import android.arch.paging.PageKeyedDataSource
import com.assessment.Articlebaseproject.model.Article
import com.assessment.Articlebaseproject.repo.web.ArticleApi
import com.assessment.Articlebaseproject.utils.State
import io.reactivex.Completable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.functions.Action
import io.reactivex.schedulers.Schedulers

class ArticleDataSource(
private val ArticleApi: ArticleApi,
private val compositeDisposable: CompositeDisposable
) : PageKeyedDataSource<Int, Article>() {

var state: MutableLiveData<State> = MutableLiveData()
private var retryCompletable: Completable? = null

override fun loadInitial(params: LoadInitialParams<Int>, callback: 
LoadInitialCallback<Int, Article>) {
    updateApiResponseState(State.LOADING)
    compositeDisposable.add(
        ArticleApi.getDeliveries(1, params.requestedLoadSize)
            .subscribe(
                { response ->
                    updateApiResponseState(State.DONE)
                    callback.onResult(response, null, 2)
                },
                {
                    updateApiResponseState(State.ERROR)
                    setRetry(Action { loadInitial(params, callback) })
                })
    )
}

private fun setRetry(action: Action) {
    retryCompletable = if (action == null) null else 
Completable.fromAction(action)
}

override fun loadAfter(params: LoadParams<Int>, callback: 
 LoadCallback<Int, Article>) {
    updateApiResponseState(State.LOADING)
    compositeDisposable.add(
        ArticleApi.getDeliveries(params.key, params.requestedLoadSize)
            .subscribe(
                { response ->
                    updateApiResponseState(State.DONE)
                    callback.onResult(
                        response,
                        params.key + params.requestedLoadSize
                    )
                },
                {
                    updateApiResponseState(State.ERROR)
                    setRetry(Action { loadAfter(params, callback) })
                }
            )
    )
}

override fun loadBefore(params: LoadParams<Int>, callback: 
LoadCallback<Int, Article>) {

}

private fun updateApiResponseState(state: State) {
    this.state.postValue(state)
}

fun retry() {
    if (retryCompletable != null) {
        compositeDisposable.add(
            retryCompletable!!
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe()
        )
    }
}
}

DataSourceFactory

package com.assessment.Articlebaseproject.repo.web.paging

import android.arch.lifecycle.MutableLiveData
import android.arch.paging.DataSource
import com.assessment.Articlebaseproject.model.Article
import com.assessment.Articlebaseproject.repo.web.ArticleApi
import io.reactivex.disposables.CompositeDisposable

class ArticleDataSourceFactory(
private val compositeDisposable: CompositeDisposable,
private val ArticleApi: ArticleApi
) : DataSource.Factory<Int, Article>() {

val ArticleDataSourceLiveData = MutableLiveData<ArticleDataSource>()

override fun create(): DataSource<Int, Article> {
    val ArticleDataSource = ArticleDataSource(ArticleApi, 
 compositeDisposable)
    ArticleDataSourceLiveData.postValue(ArticleDataSource)
    return ArticleDataSource
}
}

ViewModel

package com.assessment.Articlebaseproject.ui.ArticleList

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.Transformations.   
import android.arch.paging.LivePagedListBuilder
import android.arch.paging.PagedList
import android.view.View
import com.assessment.Articlebaseproject.base.BaseViewModel
import com.assessment.Articlebaseproject.db.dao.ArticleDao
import com.assessment.Articlebaseproject.model.Article
import com.assessment.Articlebaseproject.repo.web.ArticleApi
import com.assessment.Articlebaseproject.repo.web.paging.ArticleDataSource
import com.assessment.Articlebaseproject.repo.web.paging.ArticleDataSourceFactory
import com.assessment.Articlebaseproject.utils.State
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import javax.inject.Inject

class ArticleListViewModel(private val ArticleDao: ArticleDao) : BaseViewModel() {

val ArticleListAdapter: ArticleListAdapter
val isLoading: MutableLiveData<Int> = MutableLiveData()
var errorMsg: MutableLiveData<Int> = MutableLiveData()
var errorClick = View.OnClickListener { TODO() }
private val pageLimit: Int = 10
private val compositeDisposable = CompositeDisposable()
var ArticleList: LiveData<PagedList<Article>>
private val ArticleDataSourceFactory: ArticleDataSourceFactory

@Inject
lateinit var ArticleApi: ArticleApi

private lateinit var ArticleSubscription: Disposable

init {
    isLoading.value = View.GONE
    ArticleListAdapter = ArticleListAdapter { retry() }
    ArticleDataSourceFactory = ArticleDataSourceFactory(compositeDisposable, ArticleApi)
    val config = PagedList.Config.Builder()
        .setPageSize(pageLimit)
        .setInitialLoadSizeHint(pageLimit * 2)
        .setEnablePlaceholders(false)
        .build()
    ArticleList = LivePagedListBuilder<Int, Article>(ArticleDataSourceFactory, config).build()
}

fun getState(): LiveData<State> = Transformations.switchMap<ArticleDataSource,
        State>(ArticleDataSourceFactory.ArticleDataSourceLiveData, ArticleDataSource::state)

fun retry() {
    ArticleDataSourceFactory.ArticleDataSourceLiveData.value?.retry()
}

fun listIsEmpty(): Boolean {
    return ArticleList.value?.isEmpty() ?: true
}

override fun onCleared() {
    super.onCleared()
    ArticleSubscription.dispose()
    compositeDisposable.dispose()
}
}

Активность

package com.assessment.Articlebaseproject.ui.ArticleList

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.databinding.DataBindingUtil
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.widget.DividerItemDecoration
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import com.assessment.Articlebaseproject.R
import com.assessment.Articlebaseproject.base.BaseActivity
import com.assessment.Articlebaseproject.databinding.ActivityArticleListBinding
import com.assessment.Articlebaseproject.di.ViewModelFactory
import com.assessment.Articlebaseproject.utils.NetworkUtils

class ArticleListActivity : BaseActivity() {

private lateinit var dataBinding: ActivityArticleListBinding
private lateinit var viewModel: ArticleListViewModel

override fun layoutRes(): Int {
    return R.layout.activity_Article_list
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    dataBinding = DataBindingUtil.setContentView(this, layoutRes())
    setListView()
    viewModel = ViewModelProviders.of(this, ViewModelFactory(this))
        .get(ArticleListViewModel::class.java)
    dataBinding.viewModel = viewModel
    observeLiveData()
    if (!NetworkUtils.isConnectingToInternet(this)) {
        displayError(R.string.error_no_network)
    }
}

private fun observeLiveData() {
    viewModel.errorMsg.observe(this, Observer { error ->
        if (error != null) displayError(error) else hideError()
    })

    viewModel.ArticleList.observe(this, Observer {
        viewModel.ArticleListAdapter.submitList(it)
    })

    viewModel.getState().observe(this, Observer {
        Log.d("", it.toString())
    })
}

private fun hideError() {
    snackBar?.dismiss()
}

private fun displayError(error: Int) {
    snackBar = Snackbar.make(dataBinding.root, error, Snackbar.LENGTH_INDEFINITE)
    snackBar?.setAction(R.string.retry, viewModel.errorClick)
    snackBar?.show()
}

private fun setListView() {
    dataBinding.ArticleList.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
    dataBinding.ArticleList.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
}
}
...