У меня есть PageKeyedDataSource, который постоянно вызывает loadAfter, и все элементы добавляются в Recyclerview несколько раз. Со стороны API нулевое значение lastEvaluatedKey
означает, что мне нужно дать первую страницу, которая имеет смысл, почему он продолжает вызывать, чтобы получить первую страницу, но A. Разве это не должно прекратиться, если больше нет данных для получения (иначе params.key == null
? и B. Разве COMPARATOR
в адаптере не может запретить добавление одних и тех же элементов несколько раз? Чего мне не хватает?
PageKeyedDataSource.kt
class ReservationsPageKeyedDataSource(private val retryExecutor: Executor) : PageKeyedDataSource<String, Reservation?>() {
private var retry: (() -> Any)? = null
val initialLoad = MutableLiveData<PagingNetworkState>()
fun retryAllFailed() {
val prevRetry = retry
retry = null
prevRetry?.let {
retryExecutor.execute {
it.invoke()
}
}
}
override fun loadInitial(
params: LoadInitialParams<String>,
callback: LoadInitialCallback<String, Reservation?>
) {
val request = Api.reservationsService.getReservations(dateType = RERVATIONS_DATE_TYPE.future, last = null)
initialLoad.postValue(PagingNetworkState.LOADING)
// triggered by a refresh, execute in sync
try {
val response = request.execute()
val originalData = response.body()?.result?.reservations
val data = mutableListOf<Reservation>()
// some data munipulation
retry = null
initialLoad.postValue(PagingNetworkState.LOADED)
callback.onResult(
data.toList(),
null,
response.body()?.result?.lastEvaluatedKey.toString()
)
} catch (ioException: IOException) {
retry = {
loadInitial(params, callback)
}
val error = PagingNetworkState.error(ioException.message ?: "unknown error")
initialLoad.postValue(error)
}
}
override fun loadBefore(
params: LoadParams<String>,
callback: LoadCallback<String, Reservation?>
) {
// no-op
}
override fun loadAfter(
params: LoadParams<String>,
callback: LoadCallback<String, Reservation?>
) {
// I tried adding an if statement here to check if the params.key is null or not but that didn't help
Api.reservationsService.getReservations(dateType = RERVATIONS_DATE_TYPE.future, last = params.key)
.enqueue(object : Callback<ReservationListResponse> {
override fun onFailure(call: Call<ReservationListResponse>, t: Throwable) {
retry = { loadAfter(params, callback) }
}
override fun onResponse(
call: Call<ReservationListResponse>,
response: Response<ReservationListResponse>
) {
if (response.isSuccessful) {
val data = response.body()?.result?.reservations
retry = null
callback.onResult(
data.orEmpty(),
response.body()?.result?.lastEvaluatedKey.toString()
)
} else {
retry = { loadAfter(params, callback) }
}
}
})
}
}
Компаратор вPagedListAdapter:
companion object {
val COMPARATOR = object : DiffUtil.ItemCallback<Reservation>() {
override fun areContentsTheSame(oldItem: Reservation, newItem: Reservation): Boolean =
oldItem == newItem
override fun areItemsTheSame(oldItem: Reservation, newItem: Reservation): Boolean =
oldItem.id == newItem.id
}
}