0

I have a notification list displayed through paging. When I delete or change the status of an item, I want to refresh the page so as not to lose the item when scrolling to another page. I have used a placeholder to hold the place when refreshing and do not want to show it when loading another page, but I have encountered a problem where after refreshing one page, the pages loaded in append or prepend have errors and a series of placeholders that I do not want will appear, even though only one page has been loaded.

class NotificationListPagingSource(
   ...
) : RxPagingSource<Int, NotificationItem>() {

    override fun getRefreshKey(state: PagingState<Int, NotificationItem>): Int? {
        return state.anchorPosition?.let { anchorPosition ->
            val anchorPage = state.closestPageToPosition(anchorPosition)
            anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1) ?: 0
        }
    }

    override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, NotificationItem>> {
        val position = params.key ?: 0
        val isStateRefresh = params is LoadParams.Refresh
        return api.getNotificationList(status, position, pageSize)
            .subscribeOn(Schedulers.io())
            .map {
                toLoadResult(it, position, isStateRefresh)
            }
            .onErrorReturn {
                LoadResult.Error(it)
            }
    }

    private fun toLoadResult(
        data: ApiResponse<NotificationListResponse>,
        position: Int,
        isStateRefresh: Boolean = false
    ): LoadResult<Int, NotificationItem> {
        val itemsBefore = if (isStateRefresh) { position * pageSize } else { 0 }
        val itemsAfter = if (isStateRefresh) { (data.result?.count ?: 0) - (itemsBefore + (data.result?.data?.size ?: 0)) } else { 0 }
        return LoadResult.Page(
            data = data.result?.data.orEmpty(),
            prevKey = if (position == 0) null else position - 1,
            nextKey = if (data.result?.count == null || data.result.count == 0 || position >= ceil(data.result.count.toFloat() / pageSize).roundToInt() -1) null else position + 1 ,
            itemsBefore,
            itemsAfter
        )
    }
}
override fun getNotificationList(
        status: String?,
        pageSize: Int
    ): Flowable<PagingData<NotificationItem>> {
        return Pager(
            config = PagingConfig(
                pageSize = pageSize,
                prefetchDistance = pageSize/2,
                enablePlaceholders = true,
            ), pagingSourceFactory = {
                NotificationListPagingSource(authorizationMapApiService, status = status, pageSize = pageSize)
            }
        ).flowable
    }

and when update or delete notifcation call:

    adapterNotificationList.refresh()

I am trying to refresh a page while keeping the scroll position of an item. I have tried using RemoteMediator, but when calling adapter.refresh, it deletes all the data and loses the current scroll position.

DHP
  • 1

0 Answers0