I'm using the paging3 library with Compose Multiplatform. It's working, but I've noticed that my component that consumes the paging data is re-rendered (visible flash) each time new paging data is received.
I believe this is because of the when statement that checks for loading or error states.
I would like to add distinctUntilChangedBy to filter by events.loadstate.refresh, but it isn't available on the flow before the call to collectAsLazyPagingItems.
- How should I modify this code so that it doesn't re-render each time the number of message events changes?
- I want to just animate the changes in the list without having the whole component render, which is causing a noticeable flash right now?
This is basically a chat list. Each time a new chat message is received, it is inserted into the database and the paging data is invalidated to load the latest message.
@Composable
fun MessageList(
pager: Flow<PagingData<MessageEvent>>?,
modifier: Modifier = Modifier,
) {
pager?.let { flow ->
val events = flow.collectAsLazyPagingItems()
when (events.loadState.refresh) {
LoadStateLoading -> {
CenteredProgressIndicator()
}
is LoadStateError -> {
val errorState = events.loadState.refresh as LoadStateError
ShowError(errorState)
}
else -> {
if (events.itemCount > 0) {
LazyColumn {
items(events.itemCount) { index ->
events[index]?.let {
MessageRow(it)
}
}
}
} else {
NoMessagesAvailable(modifier)
}
}
}
}
}
The flickering occurs because for a very short moment, you set the
loadStatetoLoadStateLoadingwhile refreshing the list. Thus, for a very short moment, theCenteredProgressIndicator()is shown.You haven't provided your code where you set the
loadState. But what you could do to resolve this:CenteredProgressIndicator()at the initial loading (when the list data is still empty)PullRefresh:In order to achieve this behaviour, you can adapt your logic and introduce another LoadState:
LoadStateLoadingfor initial loading when the list is emptyLoadStateRefreshingfor refreshing when there is already data in the listThen depending on the LoadState, display an according loading animation:
With this code, you should be able to use the PullRefresh loading indicator without the pulling functionality.
Note that I am not able to test the code right now, but it should give you the idea.