Append data after load in Remote Mediator
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 38/100
Línea de trabajo
Empieza siguiendo el flujo de Pager a través de MapPagingSource.load y PokemonApiRemoteMediator.load, y después compara la secuencia registrada con el PagingData enviado al adapter. Comprueba cómo cambia el mapa en memoria durante APPEND y qué evento debería hacer visibles los datos recién cargados. Se considera terminado cuando los resultados añadidos aparecen en el adapter sin depender de un workaround no relacionado.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
I decided to try Pager without the Room database. I use HashMap as the simplest database.
First I implemented PagingSource.
class MapPagingSource(
private val map: () -> Map<Int, List<Result>>
) : PagingSource<Int, Result>() {
override fun getRefreshKey(state: PagingState<Int, Result>): Int? {
println("TAG PagingSource anchorPosition ${state.anchorPosition}")
val anchor = state.anchorPosition ?: return null
val closest = state.closestPageToPosition(anchor) ?: return null
val page = closest.prevKey?.plus(1) ?: closest.nextKey?.minus(1)
return page
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Result> {
val map = map()
val position = (params.key ?: 0)
println("TAG PagingSource position = $position, size = ${map.size}")
return LoadResult.Page(
data = map[position] ?: emptyList(),
prevKey = if (position == 0) null else position - 1,
nextKey = if (position + 1 < map.size) position + 1 else null
)
}
}
After RemoteMediator
@OptIn(ExperimentalPagingApi::class)
class PokemonApiRemoteMediator(
private val map: () -> MutableMap<Int, List<Result>>,
private val append: () -> Unit
) : RemoteMediator<Int, Result>() {
private val ktor = Ktor()
override suspend fun initialize(): InitializeAction {
println("TAG RemoteMediator initialize")
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(loadType: LoadType, state: PagingState<Int, Result>): MediatorResult {
val map = map()
println("TAG RemoteMediator $loadType, ${map.size}")
return try {
val latestPage = when (loadType) {
LoadType.REFRESH -> 0
LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
LoadType.APPEND -> map.size
}
val subList = runCatching {
withContext(Dispatchers.IO) {
ktor.getData(state.config.pageSize, latestPage * state.config.pageSize)
}
}.getOrNull()
val data =
subList?.results ?: return MediatorResult.Success(endOfPaginationReached = true)
if (data.isEmpty()) return MediatorResult.Success(endOfPaginationReached = true)
if (loadType == LoadType.REFRESH) map.clear()
map[latestPage] = data
println("TAG RemoteMediator size ${map.size}")
if (loadType == LoadType.APPEND) append()
MediatorResult.Success(false)
} catch (e: Throwable) {
println("TAG RemoteMediator $e")
MediatorResult.Error(e)
}
}
}
And created a Pager in ViewModel
private val data: MutableMap<Int, List<Result>> = HashMap()
private var latestSource: MapPagingSource? = null
@OptIn(ExperimentalPagingApi::class)
private val _pager = Pager(
config = PagingConfig(10, enablePlaceholders = false),
remoteMediator = PokemonApiRemoteMediator(map = { data }) { },
pagingSourceFactory = {
println("TAG create source")
MapPagingSource { data }.also {
latestSource = it
} }
val adapter = Adapter()
init {
_pager.flow
.onEach {
println("TAG PagingData $it")
adapter.submitData(it)
}.launchIn(viewModelScope)
}
As I can see, the PagingData was created and sent to the adapter.
Then the PagingSource did not find the data and started the RemoteMediator.
After loading, the work stopped and the PagingSource did not start loading the data.
Of course, I can call "invalidate". But this will recreate the PagingSource, and will not add the data as if it were just making requests to the network from the PagingSource.
- Lenguaje dominante
- Kotlin
- Estrellas
- 509
- Forks
- 268
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de android/codelab-android-paging
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 62/100
android/codelab-android-paging#236 · 3 reacciones ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 35/100
android/codelab-android-paging#243 · 1 comentario · 1 reacción ·
-
Dificultad 2/5 1-2 días Aptitud para principiantes 35/100
android/codelab-android-paging#241 · 1 comentario ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 15/100
Todos los issues de android/codelab-android-paging
Issues similares
-
Voratoon change link broAbiertoSource is down
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
keiyoushi/extensions-source#19491 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
MTES-MCT/rapportnav2#1557 ·
Los mantenedores suelen responder en 1 día
-
ready-for-agent
Dificultad 1/5 1-3 horas Aptitud para principiantes 86/100
emm3000/Just-Chill#543 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
vaadin/intellij-plugin#600 ·
-
more gray for disabled optionAbiertoaccessibility
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100