I am new to the paging libray, whenever i was invalidating the data source, paging brings the list to the top. I was searching through various blogs they were saying that loadInitial
,loadRange
should be called from the thread where it was started, But in my case i was using coroutine in my application, But i tried this behaviour without using coroutine everything worked as fine.
DataSource
class TestingDataSource(
private val testingViewModel: TestingViewModel, private val coroutineScope: CoroutineScope
) : PositionalDataSource<TestingData>() {
override fun loadInitial(
params: LoadInitialParams,
callback: LoadInitialCallback<TestingData>
) {
coroutineScope.launch {
testingViewModel.testingData(0, params.requestedLoadSize) {
callback.onResult(it, 0)
}
}
}
override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<TestingData>) {
coroutineScope.launch {
testingViewModel.testingData(params.startPosition, params.loadSize) {
callback.onResult(it)
}
}
}
}
DataSource Factory
class DataSourceFactory(
private val testingViewModel: TestingViewModel,
private val coroutineScope: CoroutineScope
) : DataSource.Factory<Int, TestingData>() {
val dataSource: MutableLiveData<TestingDataSource> = MutableLiveData()
override fun create(): DataSource<Int, TestingData> {
return TestingDataSource(testingViewModel, coroutineScope)
.also {
dataSource.postValue(it)
}
}
fun getDataSource(): TestingDataSource? {
return dataSource.value
}
}
ViewModel
class TestingViewModel : ViewModel() {
lateinit var dataSourceFactory: DataSourceFactory
lateinit var dataList: LiveData<PagedList<TestingData>>
var isInvalidate: Boolean = false
val list = mutableListOf<TestingData>()
fun dataSource() {
dataSourceFactory = DataSourceFactory(this, viewModelScope)
val config = PagedList.Config.Builder()
.setPageSize(20)
.setPrefetchDistance(5)
.setEnablePlaceholders(false)
.build()
dataList = LivePagedListBuilder(dataSourceFactory, config)
.build()
}
suspend fun testingData(offset: Int, limit: Int, callBack: suspend (List<TestingData>) -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
if (isInvalidate) {
callBack(list)
} else {
if (offset > 60) {
dataSourceFactory.getDataSource()?.invalidate()
isInvalidate = true
} else {
val data = getData(offset)
list.addAll(data)
callBack(data)
}
}
}
}
fun getData(offset: Int): List<TestingData> {
return (offset..offset + 20).map {
TestingData("Some_data_${it}", it.toString())
}
}
}
Can anyone suggest me how to achieve this?