How can I refresh paging adapter with scrolling back to the top automatically?

Viewed 1501

This is my first time using Paging library 3. This is my PagingSource file, For the API we have to use a cursor in order to do paging, every time I refresh the adapter it scrolls back to the top of the list, is there any way to refresh the list without scrolling to the top?

class SearchProductDataSource(
    private val searchFilter: SearchFilter,
    private val searchProductsUseCase: SearchProductsUseCase
) : PagingSource<String, Product>() {

    override fun getRefreshKey(state: PagingState<String, Product>): String? {
        return null
    }

    override suspend fun load(params: LoadParams<String>): LoadResult<String, Product> {
        try {
            val currentKey = params.key
            val newFilter: SearchFilter = searchFilter.copy(afterCursor = currentKey)
            val result = searchProductsUseCase(newFilter, params.loadSize)
            val nextKey = if (result?.pageInfo?.hasNextPage == true)
                result.cursor
            else
                null

            return LoadResult.Page(result.list, currentKey, nextKey)
        } catch (e: Exception) {
            Timber.e(e)
            return LoadResult.Error(e)
        }
    }

}

This is how I call a refresh method after updating the wishlist.

adapter.refresh()
1 Answers

You need to implement getRefreshKey to return a non-null result.

getRefreshKey is used by Paging to get the key for refresh, if you return null, that's what will be passed into params.key, which in this case, looks like it returns the first page.

Something similar to the follow may work for you:

override fun getRefreshKey(state: PagingState<String, Product>): String? {
  return state.anchorPosition?.let { anchorPosition ->
    state.closestPageToPosition(anchorPosition)?.let { anchorPage ->
      val pageIndex = pages.indexOf(anchorPage)
      if (pageIndex == 0) {
        null
      } else {
        pages[pageIndex - 1].nextKey
      }
    }
  }
}
Related