When navigating from Composable A -> Composable B, say Composable A is a Lazy List scrolled halfway down and Composable B is a Lazy List Item Details Screen. Currently, the lazy list scroll position isn't stored, and when navigating back to Composable A from B, the list starts from item index 0. We could store it in a ViewModel, and read the value back, as well as use rememberSaveable, however, I am unsure as to how to implement rememberSaveable so that it scrolls to the saved position after back navigation.
Which method would be preferred to use following good code practices?
Edit: My problem arises from the fact that the listState isn't stored when navigating back from composable B to A. So if we scroll to the bottom and select an item and look at its details, when we navigate back to the list it is scrolled to the top, instead of saving its scrollState.
My composable
val listState = rememberLazyListState()
val showTitle by remember {
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}
onShowTitle(showTitle) // don't show title when first list element is visible
LazyColumn(
state = listState,
contentPadding = PaddingValues(16.dp)
) {
item {
Text("Header 1", style = MaterialTheme.typography.h4)
}
item {
Column(Modifier.fillMaxWidth()) {
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(
"Description 1",
style = MaterialTheme.typography.subtitle1,
modifier = Modifier.padding(top = 8.dp)
)
}
Spacer(modifier = Modifier.height(48.dp))
}
}
item {
itemOfTheDay.value?.let { item->
ItemCardVertical(
item = item,
navigateToDetails = {
viewModel.selectItem(it)
navigateToDetails(it)
}
)
Spacer(modifier = Modifier.height(48.dp))
}
}
item {
Text("Header 2", style = MaterialTheme.typography.h5)
Spacer(Modifier.size(16.dp))
}
item {
StaggeredVerticalGrid(maxColumnWidth = 220.dp) {
items.value?.forEach { item->
ItemCard(item, navigateToDetails = {
viewModel.selectItem(it)
navigateToDetails(it)
})
}
My NavGraph
@Composable
fun NavGraph(startDestination: String = "Items") {
val navController = rememberNavController()
val mainViewModel: MainViewModel = viewModel()
NavHost(navController = navController, startDestination = startDestination) {
navigation(route = "Items", startDestination = MAINSCREEN) {
composable(MAINSCREEN) {
MainScreen(mainViewModel,
navigateToDetails = { smoothie ->
navController.navigate(ITEMSDETAILSSCREEN)
}
)
}
composable(
ITEMDETAILSSCREEN
) {
ItemDetails(
viewModel = mainViewModel, modifier = Modifier
.fillMaxSize()
.navigationBarsPadding()
)
}
}
}
}