안드로이드

[Android] MVVM, RxJava, Paging 활용한 리스팅

Black.bean 2021. 3. 11. 13:09
package com.drimase.pilgrimage.view

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import com.drimase.pilgrimage.R
import com.drimase.pilgrimage.TourPageAdapter
import com.drimase.pilgrimage.TourViewModel
import com.drimase.pilgrimage.source.TourDataSource
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.fragment_item_list.view.*

class TourListFragment : Fragment() {
    private val tourViewModel :TourViewModel by viewModels()
    private val tourPageAdapter : TourPageAdapter = TourPageAdapter()
    private val compositeDisposable = CompositeDisposable()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_item_list, container, false)
        val disposable = tourViewModel.getPageListObservable().subscribe {it->
            tourPageAdapter.submitList(it)
            view.recyclerView.adapter = tourPageAdapter
        }
        compositeDisposable.add(disposable)
        return view
    }

    override fun onPause() {
        super.onPause()
        TourDataSource.pageNo=1
    }

    override fun onDestroy() {
        super.onDestroy()
        compositeDisposable.clear()
    }

    companion object{
        const val TAG="LIST FRAGMENT"
    }
}

 

package com.drimase.pilgrimage

import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.paging.PagedList
import androidx.paging.RxPagedListBuilder
import com.drimase.pilgrimage.entity.Tour
import com.drimase.pilgrimage.source.TourDataSourceFactory
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable

class TourViewModel(application: Application) : AndroidViewModel(application) {
    private val repository = Repository(application)
    private val compositeDisposable = CompositeDisposable()
    private var tourDataSourceFactory :TourDataSourceFactory  = TourDataSourceFactory(repository,compositeDisposable)

    private val config = PagedList.Config.Builder()
            .setPageSize(10)
            .setInitialLoadSizeHint(10)
            .setPrefetchDistance(10)
            .setEnablePlaceholders(true)
            .build()

    private var pagedListObservable: Observable<PagedList<Tour>> =RxPagedListBuilder(tourDataSourceFactory,config).buildObservable()


    override fun onCleared() {
        compositeDisposable.clear()
        super.onCleared()
    }

    fun getPageListObservable() : Observable<PagedList<Tour>> = pagedListObservable

    companion object {
        const val TAG = "TourViewModel"
    }
}

 

package com.drimase.pilgrimage.data

import androidx.paging.DataSource
import com.drimase.pilgrimage.data.dto.Tour
import io.reactivex.disposables.CompositeDisposable

class TourDataSourceFactory(
        private val repository: Repository,
        private val compositeDisposable: CompositeDisposable
):DataSource.Factory<Int, Tour>(){
    override fun create(): DataSource<Int, Tour> {
        return TourDataSource(repository,compositeDisposable)
    }
}

 

package com.drimase.pilgrimage.source

import android.util.Log
import androidx.paging.PageKeyedDataSource
import com.drimase.pilgrimage.Repository
import com.drimase.pilgrimage.entity.Tour
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers

class TourDataSource(
        private val repository: Repository,
        private val compositeDisposable: CompositeDisposable)
    : PageKeyedDataSource<Int, Tour>(){

    override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Tour>) {
        val disposable = repository.getTours(pageNo)
                .subscribe{it ->
                    pageNo++
                    callback.onResult(it.body.items.item, null, pageNo)
                    Log.i(TAG,pageNo.toString())
                }
        compositeDisposable.add(disposable)
    }

    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Tour>) {
        //do nothing
        val disposable = repository.getTours(params.key)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { it->
                    pageNo--
                    callback.onResult(it.body.items.item, pageNo)
                    Log.i(TAG,pageNo.toString())
                }
        compositeDisposable.add(disposable)
    }

    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Tour>) {
        val disposable = repository.getTours(params.key)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { it->
                    pageNo++
                    callback.onResult(it.body.items.item, pageNo)
                    Log.i(TAG,pageNo.toString())
                }
        compositeDisposable.add(disposable)
    }

    companion object{
        var pageNo =1
        const val TAG = "TourItemDataSource"
    }
}