以前の画面の状態が意図せぬ形で復元されてしまう場合の対処法
次の様な画面遷移図のアプリを考えてみる。

今までは全ての遷移時に次の様なコードを実行していた。
fun navigate( destination: TnaNavigationDestination, route: String? = null, from: NavBackStackEntry? = navController.currentBackStackEntry ) { if (from != null && from.lifecycleIsResumed()) { navController.navigate(route ?: destination.destination) { popUpTo(navController.graph.findStartDestination().id) { saveState = true } launchSingleTop = true restoreState = true } } }
この場合、FeedByLabelScreenからnavController.popBackStack()を呼び出したときに、FeedScreenまで遡ってしまう問題に直面した。
ここでは、四角で囲まれている画面時における戻る操作でのみFeedScreenまで遡ってほしいので、そのナビゲーション時のみpopUpToを呼び出したい。
そして他にも、一度AddCountTrainingActivityScreenからFeedScreenに戻り、ボトムナビゲーションのFeedScreenに紐づいているアイコンをタップすると、今度はAddCountTrainingActivityScreenの直前の画面であるLabelListScreenに戻ってしまう問題も発生していた。
なので、LabelListScreenから四角で囲まれている画面への遷移時のみ次のコードを実行するようにした。
fun navigateAndPopUp( destination: TnaNavigationDestination, route: String? = null, from: NavBackStackEntry? = navController.currentBackStackEntry ) { if (from != null && from.lifecycleIsResumed()) { val newRoute = when (destination) { is TopLevelDestination -> { destination.destination } else -> { route ?: destination.route } } navController.navigate(newRoute) { popUpTo(navController.graph.findStartDestination().id) {} launchSingleTop = true } } }
意図せぬ画面状態の復元を避けるために、saveState=trueとrestoreState=trueを削除した。
そして、他の画面の遷移時には次のコードを実行する様にした。
fun navigate( destination: TnaNavigationDestination, route: String? = null, from: NavBackStackEntry? = navController.currentBackStackEntry ) { if (from != null && from.lifecycleIsResumed()) { navController.navigate(route ?: destination.destination) { launchSingleTop = true } } }