VideoStatusDataSource.kt
class VideoStatusDataSource(
private val categoryKey: String,
private val videosStatusApi: VideoStatusApiService
) : PagingSource<Int, VideoStatus>() {
companion object {
private const val VIDEO_STARTING_PAGE_INDEX = 0
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, VideoStatus> {
return try {
val pageIndex = params.key ?: VIDEO_STARTING_PAGE_INDEX
logger(params.key)
logger(pageIndex)
val response =
videosStatusApi.getVideoStatusByPageNumberAndCategoryName(pageIndex, categoryKey)
val jsonCategoryResponse = response.getAsJsonArray(DATA_KEY)
val videoStatusList: List<VideoStatus> = Gson().fromJson(jsonCategoryResponse)
LoadResult.Page(
data = videoStatusList.orEmpty(),
prevKey = if (pageIndex == VIDEO_STARTING_PAGE_INDEX) null else pageIndex - 1,
nextKey = if (videoStatusList.isEmpty()) null else pageIndex.plus(1)
)
} catch (exception: IOException) {
LoadResult.Error(exception)
} catch (exception: HttpException) {
LoadResult.Error(exception)
} catch (exception: Exception) {
LoadResult.Error(exception)
}
}
override fun getRefreshKey(state: PagingState<Int, VideoStatus>): Int? {
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}
}
video-API service is providing 10 results on each page but with this data source class it loads all data at once I want only the first 10 items to load initially and then use scroll first 10 items it needs to load the next 10 items here is my paging data repository
MainRepopsitory.kt
fun getVideoStatusPagingData(categoryKey: String): Pager<Int, VideoStatus> =
Pager(
config = PagingConfig(
pageSize = 10
),
pagingSourceFactory = { VideoStatusDataSource(categoryKey, videosStatusApi) }
)
ViewModel
@HiltViewModel
class PagingViewModel @Inject constructor(
private val mainRepository: MainRepository,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
) : ViewModel() {
fun getCurrentCategoryVideoStatus(categoryKey: String): Flow<PagingData<VideoStatus>> =
mainRepository
.getVideoStatusPagingData(categoryKey)
.flow.cachedIn(viewModelScope)
.flowOn(ioDispatcher)
}
This is how I'm using load function in my paging sources you can get help from this I have five to six paging sources in my app and all have same implementations like this
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Message> {
return try {
val nextPage = params.key ?: 0
chatWithSellerRequest.offset = nextPage.times(PAGE_SIZE_LIMIT)
val response = apiService.getSellerChatResponse(chatWithSellerRequest)
_chatWithSellerResultResponse.value = response.chatWithSellerResult
LoadResult.Page(
data = response.chatWithSellerResult?.messages!!,
prevKey = null,
nextKey = if (response.chatWithSellerResult.messages.isEmpty()) null else nextPage + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}