如何避免 PagingAdapter 中的重复项?

Hak*_*baş 0 android kotlin android-diffutils android-paging-3

我已经为我的 android 项目实现了 paging3。为了避免重复的项目,我创建了一个 DiffUtil.ItemCallback 对象,如下所示;

companion object {
    val diffCallback = object : DiffUtil.ItemCallback<Person>() {
        override fun areItemsTheSame(oldItem: Person, newItem: Person): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Person, newItem: Person): Boolean {
            return oldItem.id == newItem.id
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在 PagingDataAdapter 中使用了该对象;

class PersonAdapter : PagingDataAdapter<Person, PersonViewHolder>(diffCallback) 
Run Code Online (Sandbox Code Playgroud)

在视图中,我从 viewModel 获取 PaginData 并将其提交到适配器中。

    private fun observeData() {
    lifecycleScope.launch {
        viewModel.getPeople().observe(this@MainActivity, {
            pagingAdapter.submitData(lifecycle, it)
        })
    }
Run Code Online (Sandbox Code Playgroud)

在我看来,由于 DiffUtil.ItemCallback,具有相同 id 的人将不会被包含在适配器中。但它没有发生。RecyclerView 会打印每个 person 对象,即使它们具有相同的 id。

如何通过id区分数据?为什么 DiffUtil.ItemCallback 不起作用?谢谢。

Hak*_*baş 8

正如 @dlam 提到的,DiffUtil 不用于避免重复项。所以,我在 viewModel 中为我的数据源编写了过滤器;

return Pager(
        PagingConfig(pageSize = 20)
    ) {
        PersonPagingDataSource(dataSource, null)
    }.liveData.map {
        val personMap = mutableSetOf<Int>()
        it.filter { person ->
            if (personMap.contains(person.id)) {
                false
            } else {
                personMap.add(person.id)
            }
        }
    }
        .cachedIn(viewModelScope)
Run Code Online (Sandbox Code Playgroud)

因此,当一个新项目来自 DataSource 时,它​​不会通过过滤添加到我的 livedata 中。