Я пробовал версию Paging 3.0.1. Вызовы API происходят сразу после того, как я распечатал журнал. Но показанные данные дублируются. Может ли кто-нибудь сказать мне, где я ошибся?
Класс источника данных страницы
class MyPageDataSource(private val api: RetrofitInstance) :
PagingSource() {
override suspend fun load(params: LoadParams): LoadResult {
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? {
return state.anchorPosition
}
companion object {
const val FIRST_PAGE_NUMBER = 1
const val PAGE_SIZE = 20
}
}
Адаптер:
class MyListingAdapter() : PagingDataAdapter(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() {
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
> {
return Pager(
PagingConfig(
pageSize = 20,
enablePlaceholders = false,
maxSize = 40,
initialLoadSize = 20,
prefetchDistance = 10
)
) {
MyPageDataSource(RetrofitInstance())
}.flow.cachedIn(viewModelScope)
}
}
Настройка представления Recycler во фрагменте:
val myAdapter = MyListingAdapter(myActivity)
//Setup the recyclerview
binding.myList.apply {
layoutManager = when {
columnCount 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)
}
}
Подробнее здесь: https://stackoverflow.com/questions/685 ... icate-rows