RecyclerView 分页问题:分页时出现重复项目和计数不正确

RecyclerView Pagination Issue: Duplicated Items and Incorrect Count with Paging

提问人:Asikur Rahman 提问时间:11/12/2023 更新时间:11/12/2023 访问量:20

问:

我想在 RecyclerView 中实现分页。但是,我面临的问题是,当我输入我的片段时,我会得到一个包含第一页项目的列表。当我向下滚动时,列表是重复的,或者它有问题,因为在 API 中,我总共有 63 个项目。但是当我向下滚动到列表的末尾时,它正在计算适配器中的 100 多个项目。但是,我希望最初,当我进入页面时,我看到 25 个项目。当我向下滚动到最后时,应该在下一页调用 API,我将获得接下来的 25 个项目。然后,当我进一步向下滚动到底部并在第 3 页再次调用 API 时,我将获得剩余的 13 个项目。因此,最后,在向下或向上滚动时,我应该总共看到 63 个项目。

改造获取方法:

    @GET("/job/")
  fun getJobList(@Header("Authorization") token: String,
                 @Query("limit") limit: Int,
                 @Query("offset") offset: Int,
                 @Query("page") page: Int): Call<JoblistResponse>

存储库方法:

override fun getTotalJobList(context: Context,page:Int,progress:ProgressCallback):MutableLiveData<JoblistResponse> {

    progress.onStart()
    val apiServices = rInstance.getRetrofitInstance()?.create(ApiServices::class.java)
    SharedPrefDataProvider.initialize(context)
    val token = "Bearer ${SharedPrefDataProvider.getAccessToken()}"
    val limit=25
    val offset=25
    val call = apiServices?.getJobList(token,limit,offset,page)

    try {
        call?.enqueue(object : Callback<JoblistResponse> {
            override fun onResponse(
                call: Call<JoblistResponse>,
                response: Response<JoblistResponse>
            ) {
                if (response.isSuccessful && response.body() != null) {
                    jobListResponse.postValue(response.body())
                    progress.onFinish()

                } else {
                    progress.onFinish()
                }
            }

            override fun onFailure(
                call: Call<JoblistResponse>,
                t: Throwable
            ) {
                progress.onFinish()
            }
        })

    } catch (e: Exception) {
        e.printStackTrace()
        progress.onFinish()
    }
    return jobListResponse}

视图模型:

   fun getTotalJobList(context: Context,page:Int,progress:ProgressCallback):MutableLiveData<JoblistResponse>{
    return joblistRepo.getTotalJobList(context,page,progress)
}

视图片段中的观察者方法:

private fun getTotalJobList() {
    Log.d("EWNPAGE", "Job list function called")

        val joblistViewModel = ViewModelProvider(this)[JobListViewmodel::class.java]

        joblistViewModel.getTotalJobList(requireContext(),currentPage,object :ProgressCallback{
            val progress=OpusProgressLoader(requireContext())
            override fun onStart() {
                progress.customDialogFunctionality(true)
            }
            override fun onFinish() {
                progress.customDialogFunctionality(false)
            }
        }).observe(viewLifecycleOwner){joblistResponse ->
            if (joblistResponse != null) {
                if (currentPage == 1) {
                    jobList.clear()
                }

                Log.d("EWNPAGE", "Job list size: ${joblistResponse.results.size}")

                    jobList.addAll(joblistResponse.results)
                    totalPages = joblistResponse.count


                Log.d("EWNPAGE","Total items in adapter: ${jobList.size}")
                    joblistAdapter?.notifyDataSetChanged()
                if (joblistResponse.next==null){

                    Log.d("EWNPAGE", "Job list next url is null")
                    isLastPage=true
                    binding.rvJobList.clearOnScrollListeners()

                }

        }}}

在 onCreateView 方法中:

 getTotalJobList()       
joblistAdapter = JobListAdapter(jobList, this)

        binding.rvJobList.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = joblistAdapter
        }

        binding.rvJobList.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->

            val lastItemPosition =
                (binding.rvJobList.layoutManager as LinearLayoutManager).findLastVisibleItemPosition()
            val totalItemCount = binding.rvJobList.adapter?.itemCount ?: 0

            if (lastItemPosition >= totalItemCount - 1 && !isLastPage) {
                // User has scrolled to the end, trigger pagination
                currentPage++

                getTotalJobList()
            }
        }

回收机视图适配器:

class JobListAdapter(
    private val jobList:List<JoblistResponse.Result>, fragment:Fragment

) :
    RecyclerView.Adapter<JobListAdapter.JobListViewHolder>() {

    private lateinit var context: Context
    private val clickListener=fragment as OnItemClickListener
    private val addFavClickListener = fragment as AddFavClickListener
    var isSelced = false


    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): JobListAdapter.JobListViewHolder {
        context = parent.context
        val binding =
            ItemJobCardBinding.inflate(LayoutInflater.from(parent.context), parent, false)

        return JobListViewHolder(binding)
    }

    override fun onBindViewHolder(holder: JobListAdapter.JobListViewHolder, position: Int) {
        holder.bind(position)
        holder.setIsRecyclable(false)
        holder.itemView.setOnClickListener{
            clickListener.onItemClick(position,jobList[position].uuid)
        }

    }


    override fun getItemCount(): Int {
        Log.d("EWNPAGE","Total items in adapter: ${jobList.size}")
        return jobList.size
    }

    inner class JobListViewHolder(val binding: ItemJobCardBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(position: Int) {

            val job = jobList[position]

           //more codes

        }
    }
}
Kotlin Android-RecyclerView 分页 适配器

评论


答: 暂无答案