I'm using Android Jetpack Paging3 library for pagination, i have followed the google code lab and some medium blogs for reference. I have implemented pagination as they suggested but it is not working,viewmodel is always returns null value. When i debug the application got to know that PageDataSource is not calling. I don't understand where is the issue i have followed as per the articles. Following is the code snippet of my project.
This code which i'm calling Pager in my RepositoryImpl class.
override suspend fun getSearchResult(searchKey: String): LiveData<PagingData<MyDataModel>> {
return Pager(
config = PagingConfig(NETWORK_PAGE_SIZE, enablePlaceholders = false),
pagingSourceFactory = {
MyPageDataSource(searchKey)
}).liveData
}
This is my viewmodel class code
viewModelScope.launch{
searchResult.value = Resource.loading(null)
val response = repo.getSearchResult(searchKey)
searchResult.value = Resource.success(response.value)
}
This is MyPageDataSource class
override fun getRefreshKey(state: PagingState<Int, MyDataModel>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MyDataModel> {
// Start refresh at position 1 if undefined.
val page = params.key ?: INITIAL_LOAD_SIZE
val offset = params.loadSize
return try {
val response = searchRequest(searchQuery, page, offset) // its just api calling function which get result from API.
val nextKey: Int?
when (response) {
is SearchResult.Success -> {
nextKey = if (response.result.searchRes.isEmpty()) {
null
} else {
// initial load size = 3 * NETWORK_PAGE_SIZE
// ensure we're not requesting duplicating items, at the 2nd request
page + (params.loadSize / NETWORK_PAGE_SIZE)
}
LoadResult.Page(
data = response.result.searchRes,
prevKey = if (page == INITIAL_LOAD_SIZE) null else page - 1,// Only paging forward.
// assume that if a full page is not loaded, that means the end of the data
nextKey = nextKey
)
}
is SearchResult.NoResultFound -> {
nextKey = null
LoadResult.Page(
data = emptyList(),
prevKey = if (page == INITIAL_LOAD_SIZE) null else page - 1,// Only paging forward.
// assume that if a full page is not loaded, that means the end of the data
nextKey = nextKey
)
}
is SearchResult.ServerError -> {
val exception = Exception(response.message)
LoadResult.Error(exception)
}
}
} catch (e: Exception) {
e.printStackTrace()
LoadResult.Error(e)
}
}
I tried different ways to workout the pagination, finally able to achieve the result by using function return type as LiveData. After that load function triggered everything worked out.
Bellow is ViewModel code
suspend fun getSearchResult(searchKey:String):LiveData<PagingData<MyDataModel>> =repo.getSearchResult(searchKey)
in Fragment i have access it like this
lifecycleScope.launch { viewmodel.getSearchResult(searchKey)..observe(viewLifecycleOwner) {
result -> //TODO}
I have no idea why it didn't work out when i use the livedata variable to access. If there is any other solution please post it.