以前の画面の状態が意図せぬ形で復元されてしまう場合の対処法
次の様な画面遷移図のアプリを考えてみる。
今までは全ての遷移時に次の様なコードを実行していた。
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 } } }