たかぎとねこの忘備録

プログラミングに関する忘備録を自分用に残しときます。マサカリ怖い。

以前の画面の状態が意図せぬ形で復元されてしまう場合の対処法

次の様な画面遷移図のアプリを考えてみる。

今までは全ての遷移時に次の様なコードを実行していた。

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=truerestoreState=trueを削除した。

そして、他の画面の遷移時には次のコードを実行する様にした。

fun navigate(
    destination: TnaNavigationDestination,
    route: String? = null,
    from: NavBackStackEntry? = navController.currentBackStackEntry
) {
    if (from != null && from.lifecycleIsResumed()) {
        navController.navigate(route ?: destination.destination) {
            launchSingleTop = true
        }
    }
}

参考

Navigation ComposeのNavOptions - Kenji Abe - Medium