Ошибка первоначального обновления блокирует добавление нумерации страниц в Compose AndroidAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Ошибка первоначального обновления блокирует добавление нумерации страниц в Compose Android

Сообщение Anonymous »

Я попытался реализовать нумерацию страниц с помощью RemoteMediator, но столкнулся с проблемой.
Проблема: Когда RemoteMediator выполняет первоначальное обновление, возникает ошибка (из-за из-за проблем с сетью или по другим причинам), это предотвращает добавление нумерации страниц. Другими словами, прокрутка до последнего элемента не запускает операцию добавления в RemoteMediator. Однако после повторного обновления все работает как положено.
Эта проблема возникает только во время первоначального обновления.
Это ожидаемое поведение? Если да, то как мне поступить в этой ситуации? Если нет, можно ли это исправить?
Я использую Paging 3, Jetpack Compose и SQLDelight.
код
доступа в пользовательском интерфейсе:
items(users.itemCount) { index ->
users[index]?.let { user -> // Safe call with let to handle nullability
User(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
name = user.name,
id = user.id
)
}
}

Удаленный посредник:
class UsersPagingMediator(
private val api: UserApi = ServiceLocator.locate(),
private val userRepository: UserRepository = ServiceLocator.locate(),
private val database: MyDatabase = ServiceLocator.locate()
) : RemoteMediator() {

private val initialRefreshCoolDownTime = 2.minutes

//todo:label as param
override suspend fun initialize(): InitializeAction {
val lastTimeDataFetched = userRepository.getLastModifiedTimeOfRemoteKey(remoteKeyLabel)
val elapsedTimeFromLastFetch = lastTimeDataFetched?.let {
(System.currentTimeMillis() - it).milliseconds
}
return if (elapsedTimeFromLastFetch == null || elapsedTimeFromLastFetch > initialRefreshCoolDownTime) {
InitializeAction.LAUNCH_INITIAL_REFRESH
} else {
InitializeAction.SKIP_INITIAL_REFRESH
}
}

override suspend fun load(
loadType: LoadType,
state: PagingState
): MediatorResult {
Log.v("tag", "load: $loadType")
val loadKey = when (loadType) {
LoadType.REFRESH -> {
null
}

LoadType.PREPEND -> {
return MediatorResult.Success(endOfPaginationReached = true)
}

LoadType.APPEND -> {
val lastItem = state.lastItemOrNull()
val remoteKey =
database.remoteKeyQueries.getRemoteKey(remoteKeyLabel).executeAsOneOrNull()
Log.v("tag", "handling LoadType.APPEND : $remoteKey")
remoteKey?.nextKey ?: return MediatorResult.Success(endOfPaginationReached = true)
}
}
return try {
//api call
val apiResponse =
api.getUsers(offset = loadKey?.toInt() ?: 0, size = state.config.pageSize)
?: return MediatorResult.Error(Exception("Api response is null"))
val endOfPagination = apiResponse.size < state.config.pageSize
//process api data and insert into db
database.transaction {
//todo:check if rollbacks and return error
//clear if refresh, and clear all related dbs
if (loadType == LoadType.REFRESH) {
userRepository.clearUsers()
userRepository.deleteRemoteKeyByLabel(remoteKeyLabel)
}
//take care of keys(insert new key)
insertRemoteKey(
fetchedDataSize = apiResponse.size,
loadKey = loadKey?.toInt(),
pageSize = state.config.pageSize
)
//insert data into db
apiResponse.forEach(userRepository::insertUser)
}
//return success
MediatorResult.Success(endOfPaginationReached = endOfPagination)
} catch (e: CancellationException) {
Log.v("tag", "load: $e")
throw e
} catch (e: Exception) {
MediatorResult.Error(e)
}
}

private fun insertRemoteKey(fetchedDataSize: Int, loadKey: Int?, pageSize: Int) {
//insert new key
val remoteKey = when {
//if api data is empty, then put a null next key
//this will indicate that there is no more data, we already checked the api
fetchedDataSize < pageSize -> RemoteKey(
remoteKeyLabel,
null,
null,
lastModifiedTime =
System.currentTimeMillis()
)
//means we got enough data so put the next offset as nextKey,
//this will indicate that there might be more data
else -> RemoteKey(
remoteKeyLabel,
null,
((loadKey ?: 0) + pageSize).toLong(),
lastModifiedTime = System.currentTimeMillis()
)
}
Log.v("tag", "insertRemoteKey: $remoteKey")
userRepository.insertRemoteKey(remoteKey)
}

companion object {
const val remoteKeyLabel = "users"
}
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... se-android
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»