Update 1 :
You may also need to call saveState() function on navController
You can use this for handle clicks on navItem:
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
...
onClick = {
if (navItem.screen_route != currentDestination?.route) {
Log.d("Navigation", "Try to navigate")
navController.navigate(navItem.screen_route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
// Avoid multiple copies of the same destination when
if (currentDestination != null) {
Log.d("Navigation", "Pop up current destination")
popUpTo(currentDestination.id) {
saveState = true
inclusive = true
}
} else {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
inclusive = true
}
}
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
}
}
...
and you should be use rememberSaveable for saveable values
Restoring state in Compose
Use rememberSaveable to restore your UI state after an activity or process is recreated. rememberSaveable retains state across recompositions. In addition, rememberSaveable also retains state across activity and process recreation.
Ways to store state
All data types that are added to the Bundle are saved automatically. If you want to save something that cannot be added to the Bundle, there are several options.
Parcelize
The simplest solution is to add the @Parcelize annotation to the object. The object becomes parcelable, and can be bundled. For example, this code makes a parcelable City data type and saves it to the state.
Like this :
@Parcelize
data class City(val name: String, val country: String) : Parcelable
@Composable
fun CityScreen() {
var selectedCity = rememberSaveable {
mutableStateOf(City("Madrid", "Spain"))
}
}
Also, you can use MapSaver like this :
data class City(val name: String, val country: String)
val CitySaver = run {
val nameKey = "Name"
val countryKey = "Country"
mapSaver(
save = { mapOf(nameKey to it.name, countryKey to it.country) },
restore = { City(it[nameKey] as String, it[countryKey] as String) }
)
}
@Composable
fun CityScreen() {
var selectedCity = rememberSaveable(stateSaver = CitySaver) {
mutableStateOf(City("Madrid", "Spain"))
}
}
And also, ListSaver :
data class City(val name: String, val country: String)
val CitySaver = listSaver<City, Any>(
save = { listOf(it.name, it.country) },
restore = { City(it[0] as String, it[1] as String) }
)
@Composable
fun CityScreen() {
var selectedCity = rememberSaveable(stateSaver = CitySaver) {
mutableStateOf(City("Madrid", "Spain"))
}
}
Probably, with the information I provided, you don't need to refer to the reference sources. Just try coding !