1

I set up navigation, pagination and use flow to connect ui with model. If simplify, my screen code looks like this:

@Composable
MainScreen() {
    val listState = rememberLazyListState()
    val lazyItems = Pager(PagingConfig(...)) { ... }
        .flow
        .cachedIn(viewModelScope)
        .collectAsLazyPagingItems()

    LazyColumn(state = listState) {
        items(lazyItems, key = { it.id }) { ... }
    }
}

And here is my NavHost code:

NavHost(navController, startDestination = "mainScreen") {
    composable("mainScreen") {
        MainScreen()
    }
}

But when i navigate back to MainScreen from another screen or just opening the drawer, data is loaded from DataSource again and i see noticeable blink of LazyColumn.

How to avoid reloading data?

1 Answers1

6

Your code gives me the following error for cachedIn:

Flow operator functions should not be invoked within composition

You shouldn't ignore such warnings.

During transition Compose Navigation recomposes both disappearing and appearing views many times. This is the expected behavior.

And your code creates a new Pager with a new flow on each recomposition, which is causing the problem.

The easiest way to solve it is using remember: it'll cache the pager flow between recompositions:

val lazyItems = remember {
    Pager(PagingConfig(/* ... */)) { /* ... */ }
        .flow
        .cachedIn(viewModelScope)
        .collectAsLazyPagingItems()
}

But it'll still be reset during configuration change, e.g. device rotation. The best way to prevent this is moving this logic into a view model:

class MainScreenViewModel : ViewModel() {
    val pagingFlow = Pager(PagingConfig(/* ... */)) { /* ... */ }
        .flow
        .cachedIn(viewModelScope)
}

@Composable
fun MainScreen(
    viewModel = viewModel<MainScreenViewModel>()
) {
    val lazyItems = viewModel.pagingFlow.collectAsLazyPagingItems()
}
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • It didn't helped in my case, after navigating back `lazyItems.itemCount` shows 0 for about 100 milliseconds and it cause flickering. Paging version is `3.1.1` – Akbolat SSS Apr 04 '22 at 08:42
  • @AkbolatSSS Check out [this answer](https://stackoverflow.com/a/69491725/3585796), if it's not the case - ask a separate question with more details and [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Phil Dukhov Apr 04 '22 at 08:47
  • not my case, not pure Compose for now. But I've found that `collectAsLazyPagingItems#collectPagingData` triggers with a delay, which cause zero items at first – Akbolat SSS Apr 04 '22 at 09:16