Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Calling refresh() method twice, stops the pagination.

未关闭
#223 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
android, kotlin
领域
mobile

调研方向

首先,使用提供的 pull-to-refresh 流程复现 VideosFragment 中的双重刷新行为,然后结合 VideoPagingSource.kt 和 PreClassViewModel.kt 跟踪 adapter.refresh()、submitData() 以及 loadStateFlow。完成标准是:调用两次 refresh() 后分页仍能正常工作,并且刷新状态仍能正确清除。

由索引模型根据 Issue 内容生成。

描述

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) {

    }

}
主要语言
Kotlin
星标
509
派生
268
PR 合并指标
30 天内没有已合并 PR

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

android/codelab-android-paging 的其他 Issue

查看 android/codelab-android-paging 的全部 Issue

相似的 Issue

更多 Kotlin Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。