You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免PagingAdapter出现重复条目?DiffUtil.ItemCallback不生效怎么办

为什么你的DiffUtil配置没有生效

你对DiffUtil.ItemCallback的功能存在认知偏差,它的核心作用是对比适配器已加载的旧数据集和新提交的PagingData的差异,用于生成RecyclerView的局部更新指令(比如条目新增/删除/修改的动画、局部刷新),不会对单个PagingData内部的重复数据、或跨页加载的重复数据做自动过滤。
简单说:如果你的数据源本身返回的PagingData就包含多个相同ID的Person对象,DiffUtil不会主动删除这些重复条目,只会判断两个条目是否是同一个对象、是否需要刷新内容,完全没有去重的作用。

实现按ID去重的可行方案

推荐按优先级从高到低选择以下方案:

  • 数据源层去重(最优方案)
    从数据产生的源头处理重复问题,避免后续所有链路的冗余处理:

    1. 如果是直接从网络加载分页的PagingSource,在load方法拿到接口返回的列表后,先按ID去重再封装为LoadResult.Page返回,示例代码:
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Person> {
        return try {
            val page = params.key ?: 1
            val response = apiService.getPersonList(page, params.loadSize)
            // 按ID去重
            val uniqueList = response.data.distinctBy { it.id }
            LoadResult.Page(
                data = uniqueList,
                prevKey = if (page == 1) null else page - 1,
                nextKey = if (uniqueList.isEmpty()) null else page + 1
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }
    
    1. 如果用了RemoteMediator做本地+网络的分页架构,直接在Room数据库的Person表的id字段加@PrimaryKey唯一约束,重复ID的条目写入时会自动覆盖/跳过,从本地查询返回的列表自然不会有重复。
  • PagingData变换层去重
    如果无法修改数据源,可在ViewModel层对PagingData流做变换去重,示例代码:

    fun getPeople(): Flow<PagingData<Person>> {
        val existedIds = mutableSetOf<Int>()
        return Pager(
            config = PagingConfig(pageSize = 20, enablePlaceholders = false)
        ) {
            PersonPagingSource()
        }.flow.map { pagingData ->
            pagingData.filter { person ->
                val notExisted = !existedIds.contains(person.id)
                if (notExisted) existedIds.add(person.id)
                notExisted
            }
        }
    }
    

    注意该方案需要处理刷新场景,下拉刷新时需要清空existedIds集合避免新数据被误过滤。

内容的提问来源于stack exchange,提问作者Hakan Erbaş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:57:02