android / codelab-android-paging

Jetpack Paging codelab
Apache License 2.0
491 stars 260 forks source link

Calling refresh() method twice, stops the pagination. #223

Open akritkhanna opened 2 years ago

akritkhanna commented 2 years ago

I'm able to populate the list and pagination is working as expected. But when I call adapter.refresh() method twice by using pull to refresh, the pagination stops working.

Please refer the below video to get the better idea about the prolem. https://www.dropbox.com/s/0k2g9mlktv5gee6/22-05-22-10-26-37.mp4?dl=0

VideoPagingSource.kt

class VideoPagingSource(
    private val apiInterface: ApiInterface,
    private val schoolId: String,
    private val ordering: String?,
    private val courseId: String?,
    private val moduleId: String?,
    private val searchText: String?
) : PagingSource<Int, Video>() {

    override fun getRefreshKey(state: PagingState<Int, Video>): Int? = null

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Video> {
        val pageNumber = params.key
        return try {
            val response = apiInterface.getVideos(schoolId, ordering, courseId, moduleId, searchText, pageNumber)
            val pagedResponse = response?.body()
            var nextPageNumber: Int? = null
            if (pagedResponse?.links?.next != null) {
                val uri = Uri.parse(pagedResponse.links.next)
                val nextPageQuery = uri.getQueryParameter("page")
                nextPageNumber = nextPageQuery?.toInt()
            }

            LoadResult.Page(
                data = response?.body()?.objects.orEmpty(),
                prevKey = null,
                nextKey = nextPageNumber
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }

}

PreClassViewModel.kt

class PreClassViewModel @Inject constructor(private val repository: PreClassRepository) :
    ViewModel() {

    private val queryParamLiveData = MutableLiveData<QueryParams>()

    val videosLiveData = queryParamLiveData.switchMap {

        repository.getVideos(
            schoolId = it.extraArgs[0],
            ordering = it.extraArgs[1],
            courseId = it.courseId,
            moduleId = it.chapterId,
            searchText = it.searchText
        ).cachedIn(viewModelScope)

    }

    fun setQueryParam(queryParams: QueryParams){
        queryParamLiveData.value = queryParams
    }

}

VideosFragment.kt

class VideosFragment : BaseFragment<FragmentVideosBinding>(FragmentVideosBinding::inflate),
    VideosPagingAdapter.VideoClickListener {

    private val viewModel by viewModels<PreClassViewModel>()
    private var chapter: ModulesItem? = null
    private var courseId: String? = null
    private var adapter: VideosPagingAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        chapter = Gson().fromJson(arguments?.getString(BUNDLE_CHAPTER), ModulesItem::class.java)
        courseId = arguments?.getString(BUNDLE_COURSE_ID)

        viewModel.setQueryParam(
            QueryParams(
                courseId = courseId,
                chapterId = chapter?.id.toString(),
                searchText = null,
                me?.academicProfile?.school?.id?.toString()!!,
                "sequence",
            )
        )

    }

    override fun initView() {
        getMainActivity().showBothNavigation()
        getMainActivity().showBackButton()

        adapter = VideosPagingAdapter(chapter?.imageUrl, this)
        binding.videoRV.adapter = adapter!!.withLoadStateFooter(footer = DefaultFooterAdapter())
        lifecycleScope.launch {
            adapter?.loadStateFlow?.collectLatest {

                binding.progressBar.isVisible = it.refresh is LoadState.Loading

                if (binding.swipeContainer.isRefreshing){
                    binding.swipeContainer.isRefreshing = it.refresh is LoadState.Loading
                }

            }
        }

    }

    override fun initListener() {
        binding.swipeContainer.setOnRefreshListener {
            adapter?.refresh()
        }
    }

    override fun addObserver() {

        viewModel.videosLiveData.observe(viewLifecycleOwner) {
            adapter?.submitData(viewLifecycleOwner.lifecycle, it)

        }

    }

    override var setSelection: String
        get() = Constants.FEATURE_LEARN
        set(value) {}

    override fun onVideoClick(video: Video) {

    }

}
baishyamridul commented 1 year ago

@akritkhanna Facing same issue, have you fixed it ?

akritkhanna commented 1 year ago

@akritkhanna Facing same issue, have you fixed it ?

@baishyamridul No, I switched to traditional approach for the pagination but this time I used BaseAdapter class with diffUtil. In that I was facing the same issue but I was able to fix it by using the extension function. yourList.toMutableList() Let me know if this works the paging library.

DawnNguyenAhiho commented 3 months ago

I'm facing the same issue, too. But when I update the pagingConfig, using pageSize = 20, everything just gone, the pagination always work no matter how many time I refresh. Hope this will help