【问题标题】:Android Paging 3 leading to duplicate rowsAndroid Paging 3导致重复行
【发布时间】:2021-10-05 01:28:31
【问题描述】:

我正在试用 Paging 3.0.1 版本。当我打印日志时,API 调用正在发生。但显示的数据是重复的。谁能告诉我哪里出错了?

页面数据源类

class MyPageDataSource(private val api: RetrofitInstance) :
PagingSource<Int, APIDataResponse>() {

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, APIDataResponse> {
    return try {
        val nextPageNumber = params.key ?: FIRST_PAGE_NUMBER
        val response = api.getData(nextPageNumber, PAGE_SIZE)
        LoadResult.Page(
            data = response.APIS!!,
            prevKey = if (nextPageNumber > FIRST_PAGE_NUMBER) nextPageNumber - 1 else null,
            nextKey = if (nextPageNumber * PAGE_SIZE < response.total!!) nextPageNumber + 1 else null
        )
    } catch (e: Exception) {
        LoadResult.Error(e)
    }
}

override fun getRefreshKey(state: PagingState<Int, APIDataResponse>): Int? {
    return state.anchorPosition
}

companion object {
    const val FIRST_PAGE_NUMBER = 1
    const val PAGE_SIZE = 20
}
}

适配器:

class MyListingAdapter() : PagingDataAdapter<APIDataResponse, MyListingAdapter.MyViewHolder>(MyComparator) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    return MyViewHolder(
        FragmentItemBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
    )
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    holder.bind(item = getItem(position))
}

inner class MyViewHolder(binding: FragmentItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    private val title: TextView = binding.title

    fun bind(item: APIDataResponse?) {
        if(item != null) {
            title.text = item.title
        }
    }
}

object MyComparator : DiffUtil.ItemCallback<APIDataResponse>() {
    override fun areItemsTheSame(
        oldItem: APIDataResponse,
        newItem: APIDataResponse
    ): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(
        oldItem: APIDataResponse,
        newItem: APIDataResponse
    ): Boolean {
        return oldItem == newItem
    }
}
}

查看模型:

class PagingViewModel : ViewModel() {

fun getData() : Flow<PagingData<APIDataResponse>> {
    return Pager(
        PagingConfig(
            pageSize = 20,
            enablePlaceholders = false,
            maxSize = 40,
            initialLoadSize = 20,
            prefetchDistance = 10
        )
    ) {
        MyPageDataSource(RetrofitInstance())
    }.flow.cachedIn(viewModelScope)
}
}

在片段中设置回收站视图:

val myAdapter = MyListingAdapter(myActivity)

    //Setup the recyclerview
    binding.myList.apply {
        layoutManager = when {
            columnCount <= 1 -> LinearLayoutManager(context)
            else -> GridLayoutManager(context, columnCount)
        }
        myAdapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
        val decoration =
            DividerItemDecoration(myActivity, DividerItemDecoration.VERTICAL)
        addItemDecoration(decoration)
        setHasFixedSize(true)
        adapter = myAdapter
    }
    lifecycleScope.launch {
        viewModel.getData().distinctUntilChanged().collectLatest { pagedData ->
            myAdapter.submitData(pagedData)
        }
    }

【问题讨论】:

  • 嗨,您能解释一下您在 nextKey 中尝试做什么吗?因为那是用来检查我们是否需要加载更多页面,所以我在那里完成的实现是 nextKey = if (response.isEmpty()) null else position + 1,这与你的 api 的工作方式有关吗?
  • 每页包含 20 个结果,即 PAGE_SIZE。 nextPageNumber * PAGE_SIZE 将返回加载的结果数。我的 API 返回了总字段。所以,我正在检查乘积与总数。
  • 您的APIDataResponse 是“数据类”吗?在我看来,重复发生在DiffUtil.ItemCallback
  • @A.David 是的,它是一个数据类

标签: android kotlin paging android-paging android-paging-3


【解决方案1】:

我遇到了同样的问题。 它通过设置正确的pageSize来解决。

设置错误的maxSizeinitialLoadSize 或其他属性也可能出现此问题。

【讨论】:

    【解决方案2】:

    你已经设置了 setHasFixedSize(true) 这意味着数据不会因为适配器内容的改变而改变。例如,RecyclerView 的大小可能会因为其父级的大小变化而发生变化。也许这就是您获得相同记录的原因。尝试删除它,然后检查它是否有效。

    【讨论】:

      猜你喜欢
      • 2021-12-13
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 2020-12-15
      • 2021-11-05
      • 1970-01-01
      • 2021-06-23
      相关资源
      最近更新 更多