I was trying out the Paging 3.0.1 version. The API calls are happening right when I printed the log. But the data shown is duplicate. Could someone tell me where I went wrong?
Page data source class
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
}
}
Adapter:
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
}
}
}
View Model:
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)
}
}
Recycler view setting up in the fragment:
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)
}
}
from Android Paging 3 leading to duplicate rows
No comments:
Post a Comment