Даже если следующий ответит на мой собственный вопрос, для логики сети базы данных, где данные могут изменяться, этого решения недостаточно, поскольку оно не обрабатывает обновления данных, уже сохраненных в базе данных.
Проститеколичество абстрактных классов - я обычно работаю над расширением и возможностью повторного использования.Кроме того, простите за смешение кода Java и кода Kotlin ... по какой-то причине некоторые библиотеки не были опознаны в моем проекте, использующем Kotlin, но не стесняйтесь использовать Kotlin в этих случаях.новый DataSource
класс
abstract class MyDataSource<Value>: PositionalDataSource<Value>() {
override fun loadInitial(params: PositionalDataSource.LoadInitialParams, callback: PositionalDataSource.LoadInitialCallback<Value>) {
callback.onResult(getDataFromDatabase(params.requestedLoadSize, params.requestedStartPosition)?: listOf(), 0)
}
override fun loadRange(params: PositionalDataSource.LoadRangeParams, callback: PositionalDataSource.LoadRangeCallback<Value>) {
callback.onResult(getDataFromDatabase(params.loadSize, params.startPosition)?: listOf())
}
abstract fun getDataFromDatabase(limit: Int, offset: Int): List<Value>?
}
Реализованный Concert
класс данных:
class ConcertDataSource : MyDataSource<Concert>() {
override fun getDataFromDatabase(limit: Int, offset: Int): List<Concert>? {
return ConcertAA.getConcerts(limit, offset)
}
}
Затем нам нужен DataSourceFactory
, который будет создавать наш экземпляр DataSource:
abstract class MyDataSourceFactory<Key, Value> : DataSource.Factory<Key, Value>() {
val mutableLiveData: MutableLiveData<DataSource<Key, Value>>? = null
override fun create(): DataSource<Key, Value> {
val dataSource = createDataSource()
mutableLiveData?.postValue(dataSource)
return dataSource
}
abstract fun createDataSource(): DataSource<Key, Value>
}
И реализованный DataSourceFactory для ConcertDataSource:
class ConcertDataSourceFactory : MyDataSourceFactory<Int, Concert>() {
override fun createDataSource(): DataSource<Int, Concert> {
return ConcertDataSource()
}
}
Затем ViewModel
для PagedList
, который будет иметь наш источник данных:
public class ConcertViewModel extends ViewModel {
public final LiveData<PagedList<Concert>> concertList;
private FetchCallback callback;
private final int pageSize = 10
PagedList.BoundaryCallback<Concert> boundaryCallback = new PagedList.BoundaryCallback<Concert>(){
boolean frontLoaded =false;
public void onZeroItemsLoaded() {
// callback.fetch(...);
}
public void onItemAtFrontLoaded(@NonNull Concert itemAtFront) {
if(!frontLoaded) {
// callback.fetch(...);
}
frontLoaded = true;
}
public void onItemAtEndLoaded(@NonNull Concert itemAtEnd) {
// callback.fetch(...);
}
};
public ConcertViewModel(FetchCallback callback) {
this.callback = callback;
ConcertDataSourceFactory dataSourceFactory = new ConcertDataSourceFactory();
PagedList.Config config = new PagedList.Config.Builder()
.setPageSize(pageSize)
.setInitialLoadSizeHint(pageSize)
.setEnablePlaceholders(false)
.build();
concertList = new LivePagedListBuilder<>(dataSourceFactory, config).setBoundaryCallback(boundaryCallback).build();
}
public void refresh() {
conertList.getValue().getDataSource().invalidate();
}
}
Мы используемBoundaryCallback
для прослушивания всякий раз, когда PagedList требуется загружать больше, когда он достигает какой-либо из сторон списка, и данные нашей базы данных не содержат никаких дополнительных данных.Это позволит получать больше данных с сервера (или любого поставщика данных).Выборка вызывается с помощью настраиваемого обратного вызова:
interface FetchCallback{
fun fetch(limit: Int?, concertIdOffset: String?)
}
Теперь, поскольку нам нужно передать обратный вызов нашему ViewModel
, нам нужно сообщить ViewModelProviders
, как создать новый экземпляр ViewModel
с параметрами.Это делается с помощью ViewModelProvider.Factory
:
abstract class MyViewModelFactory(
private val callback: FetchCallback) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return createViewModel(callback)
}
abstract fun <T : ViewModel> createViewModel(callback: FetchCallback): T
}
И нашей реализованной ViewModelFactory
для концерта:
class ConcertViewModelFactory(callback: FetchCallback) : MyViewModelFactory(callback) {
override fun <T : ViewModel> createViewModel(callback: FetchCallback): T {
return ConcertViewModel(callback) as T
}
}
Наконец, мы инициализируем ViewModel
с нашей точки зрения (Activity
, Fragment
и т. Д.):
val factory = ConcertViewModelFactory(
object: FetchCallback{
override fun fetch(limit: Int?, eventIdOffset: String?, level: RequestParameters.RequestLevel, showLoader: Boolean) {
//Do the call to the server
}
})
viewModel = ViewModelProviders.of(this, factory).get(ConcertViewModel::class.java)
adapter = ConcertAdapter()
viewModel.concertList.observe(viewLifecycleOwner, Observer(adapter::submitList))
Это будет ответом на мой вопрос, однако обратите внимание, что (по крайней мере, на данный момент) библиотека подкачки для Android не обрабатывает изменяемые данные.Например, если у концерта есть список групп, которые могут измениться (например, одна из групп не может попасть на концерт), логика не может обновить данные, сохраненные в базе данных, поскольку она запрашивает дополнительные данные только на сервере, когдадостигает любой из границ (сверху или снизу) данных, хранящихся в базе данных.Следовательно, для моих собственных целей эта библиотека бесполезна.