Hakan Erbaş
Hakan Erbaş

Reputation: 189

How to avoid duplicate items in PagingAdapter?

I have implemented paging3 for my android project. To avoid duplicated items, I created a DiffUtil.ItemCallback object as follow;

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
        }
    }
}

And I used that object in PagingDataAdapter;

class PersonAdapter : PagingDataAdapter<Person, PersonViewHolder>(diffCallback) 

In View, I got the PaginData from viewModel and submit it into the adapter.

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

In my opinion, the persons who have the same id will not be included in the adapter thanks to DiffUtil.ItemCallback. But it didn't happen. RecyclerView prints every person object even if they have the same id.

How can I distinct the data by id? Why didn't DiffUtil.ItemCallback work? Thanks.

Upvotes: 0

Views: 1937

Answers (1)

Hakan Erbaş
Hakan Erbaş

Reputation: 189

As @dlam mentioned, DiffUtil is not used for avoiding duplicate items. So, I wrote filter for my datasource in 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)

So, when a new item comes from DataSource, It will not be added to my livedata by filtering.

Upvotes: 9

Related Questions