Having ViewModel with this code:
private var _data: MutableStateFlow<PagingData<Pokemon>> = MutableStateFlow(PagingData.empty())
val data: StateFlow<PagingData<Pokemon>> = _data.asStateFlow()
allows me to get the paged data by calling the following in the composable:
val pagingItems = viewModel.data.collectAsLazyPagingItems()
the thing is, that I have my data inside a state/data object like this:
data class UiState(
var loading: Boolean = false,
var error: Boolean = false,
val dataSource: PagingData<Pokemon> = PagingData.empty(),
)
and my ViewModel then has:
private var _state: MutableStateFlow<UiState> = MutableStateFlow(UiState(loading = true))
val state: StateFlow<UiState> = _state.asStateFlow()
How do I collect the dataSource of the UiState then in my composable? I am using the following but whenever the RemoteMediator is loading new data, the list scrolls up to almost the top.
//Not working, scrolling list to top when paging
val state by viewModel.state.collectAsState()
val pagingItems = flowOf(state.dataSource).collectAsLazyPagingItems()
and the screen:
@Composable
fun PokemonListScreen(navController: NavController, pokemon: LazyPagingItems<Pokemon>) {
LazyColumn(
modifier = Modifier.padding(4.dp)
) {
item { Spacer(modifier = Modifier.padding(4.dp)) }
items(count = pokemon.itemCount, key = pokemon.itemKey { it.id }) { index ->
pokemon[index]?.let { poke ->
PokemonItem(
poke,
onRepoClicked = {
navController.navigate(Routes.RepoDetailScreen.route)
}
)
}
}
pokemon.apply {
when {
loadState.refresh is LoadState.Loading -> {
item { PageLoader(modifier = Modifier.fillParentMaxSize()) }
}
loadState.refresh is LoadState.Error -> {
val error = pokemon.loadState.refresh as LoadState.Error
item {
ErrorMessage(
modifier = Modifier.fillParentMaxSize(),
message = error.error.localizedMessage,
onClickRetry = { retry() })
}
}
loadState.refresh is LoadState.NotLoading && pokemon.itemCount > 0 -> {
item {
ErrorMessage(
modifier = Modifier.fillParentMaxSize(),
message = stringResource(id = R.string.str_no_results),
onClickRetry = { retry() })
}
}
loadState.append is LoadState.Loading -> {
item { LoadingNextPageItem(modifier = Modifier) }
}
loadState.append is LoadState.Error -> {
val error = pokemon.loadState.append as LoadState.Error
item {
ErrorMessage(
modifier = Modifier,
message = error.error.localizedMessage,
onClickRetry = { retry() })
}
}
}
}
item { Spacer(modifier = Modifier.padding(4.dp)) }
}
}
Every time your view recomposes this line is causing the issue...
Try replacing it with this: