Last active
December 20, 2019 09:21
-
-
Save oligazar/7a92231bbebe483ad0d27547835d2e8d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.arch.lifecycle.LiveData | |
import android.arch.lifecycle.MutableLiveData | |
import android.arch.paging.PageKeyedDataSource | |
import android.arch.paging.PagedList | |
import kotlinx.coroutines.experimental.Dispatchers | |
import kotlinx.coroutines.experimental.GlobalScope | |
import kotlinx.coroutines.experimental.android.Main | |
import kotlinx.coroutines.experimental.launch | |
import us.kostenko.architecturecomponentstmdb.details.model.Movie | |
import us.kostenko.architecturecomponentstmdb.details.repository.persistance.MovieDao | |
import us.kostenko.architecturecomponentstmdb.master.repository.webservice.MoviesWebService | |
class MoviesRepository(private val webService: MoviesWebService, | |
private val movieDao: MovieDao) { | |
// fun getMovies(): LiveData<ArrayList<Movie>> { | |
// val ldMovies = MutableLiveData<ArrayList<Movie>>() | |
// GlobalScope.launch { | |
// val movies = webService.getMovies().await() | |
// ldMovies.postValue(movies.results) | |
// } | |
// return ldMovies | |
// } | |
fun getMovies(): LiveData<PagedList<Movie>> { | |
val movieData = MutableLiveData<PagedList<Movie>>() | |
val config = PagedList.Config.Builder() | |
.setPageSize(10) | |
.setEnablePlaceholders(true).build() | |
val dataSource = MoviesDataSource() | |
val list = PagedList.Builder(dataSource, config) | |
.setFetchExecutor { GlobalScope.launch(Dispatchers.Main) { it.run() } } | |
.setNotifyExecutor { GlobalScope.launch(Dispatchers.Main) { it.run() } }.build() | |
movieData.value = list | |
return movieData | |
} | |
// val factory = | |
// val liveDataPl = LivePagedListBuilder<Int, Movie>(factory, config).build() | |
inner class MoviesDataSource: PageKeyedDataSource<Int, Movie>() { | |
override fun loadInitial(params: LoadInitialParams<Int>, | |
callback: LoadInitialCallback<Int, Movie>) { | |
GlobalScope.launch { | |
val response = webService.getMovies(1).await() | |
if (params.placeholdersEnabled) { | |
callback.onResult(response.results, 0, response.totalResults, null, 2) | |
} else { | |
callback.onResult(response.results, null, 2) | |
} | |
} | |
} | |
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Movie>) { | |
GlobalScope.launch { | |
val movies = webService.getMovies(params.key).await().results | |
callback.onResult(movies, params.key + 1) | |
} | |
} | |
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Movie>) { } | |
} | |
inner class MovieBoundaryCallback: PagedList.BoundaryCallback<Movie>() { | |
private var isLoading = false | |
override fun onItemAtEndLoaded(itemAtEnd: Movie) { | |
super.onItemAtEndLoaded(itemAtEnd) | |
val position = 1 // TODO: how to compute page? | |
if (isLoading) return | |
GlobalScope.launch { | |
isLoading = true | |
val response = webService.getMovies(position).await() | |
movieDao.saveMovies(response.results) | |
isLoading = false | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
override fun onActivityCreated(savedInstanceState: Bundle?) { | |
super.onActivityCreated(savedInstanceState) | |
// viewModel.movies.observe(this, Observer { | |
// Timber.d("movies: $it") | |
// }) | |
val dataSource = MoviesDataSource(RetrofitManager.createService(activity!!.application, MoviesWebService::class.java)) | |
val config = PagedList.Config.Builder() | |
.setEnablePlaceholders(false) | |
.build() | |
// | |
val pagedList = PagedList.Builder(dataSource, config) | |
.setFetchExecutor(Executors.newSingleThreadExecutor()) | |
.setNotifyExecutor(MainThreadExecutor()) | |
.build() | |
val diffUtilCallback = MovieDiffUtilCallback() | |
val movieAdapter = MoviesAdapter(diffUtilCallback) | |
movieAdapter.submitList(pagedList) | |
recycler.apply { | |
adapter = movieAdapter | |
layoutManager = GridLayoutManager(activity, 2) | |
addItemDecoration(GridItemDecorator(2, 8, 8,true)) | |
setHasFixedSize(true) | |
} | |
} | |
internal inner class MainThreadExecutor : Executor { | |
private val mHandler = Handler(Looper.getMainLooper()) | |
override fun execute(command: Runnable) { | |
mHandler.post(command) | |
} | |
} | |
class MoviesDataSource(private val service: MoviesWebService): PageKeyedDataSource<Int, Movie>() { | |
override fun loadInitial(params: LoadInitialParams<Int>, | |
callback: LoadInitialCallback<Int, Movie>) { | |
Timber.d("loadInitial, requestedLoadSize: ${params.requestedLoadSize}, placeholdersEnabled: ${params.placeholdersEnabled}") | |
service.getMovies(1).enqueue(object: Callback<Movies> { | |
override fun onFailure(call: Call<Movies>, t: Throwable) { | |
Timber.d("call: $call, error: $t") | |
} | |
override fun onResponse(call: Call<Movies>, response: Response<Movies>) { | |
val movies = response.body()?.results | |
if (movies != null) { | |
callback.onResult(movies, null, 2) | |
} else { | |
Timber.d("call: $call, response: $response") | |
} | |
} | |
}) | |
} | |
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Movie>) { | |
Timber.d("loadAfter, key: ${params.key}, requestedLoadSize: ${params.requestedLoadSize}") | |
service.getMovies(params.key).enqueue(object: Callback<Movies> { | |
override fun onFailure(call: Call<Movies>, t: Throwable) { | |
Timber.d("call: $call, error: $t") | |
} | |
override fun onResponse(call: Call<Movies>, response: Response<Movies>) { | |
val movies = response.body()?.results | |
if (movies != null) { | |
callback.onResult(movies, params.key + 1) | |
} else { | |
Timber.d("call: $call, response: $response") | |
} | |
} | |
}) | |
} | |
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Movie>) { } | |
// TODO: implement this and save page position in onSavedInstanceState to resume work after app is killed | |
} | |
internal inner class MovieDiffUtilCallback: DiffUtil.ItemCallback<Movie>() { | |
override fun areItemsTheSame(p0: Movie, p1: Movie) = p0.id == p1.id | |
override fun areContentsTheSame(p0: Movie, p1: Movie) = p0 == p1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment