Navigation Composeでも NavOptions
が設定でき、画面遷移を細かく制御できるようになっています。この NavOptions
の挙動についてまとめておきます。
NavGraph
今回使用するNavGraphの定義は以下のようなシンプルな構成を考えます。
launchSingleTop
オプションなしの画面遷移では、バックスタックのトップにある(今表示されてる)画面から同じ画面に遷移した場合、同じ画面が上に積まれることになります。遷移後にバックキーを押すと同じ画面がまた表示される感じです。
navController.navigate("screen_a")
launchSingleTop
を使うと、バックスタックのトップにある画面から同じ画面を表示した場合は、同じ画面がそのまま再利用されます。
navController.navigate("screen_a") {
launchSingleTop = true
}
これはトップにあるときだけなので、間に別の画面がある場合は、オプション無しの遷移と同様です。
popUpTo
popUpTo
を使った場合は遷移する前に、指定したrouteに一致する画面までバックスタックから取り出します。
navController.navigate("screen_d") {
popUpTo("screen_a")
}
この例だと、CとBをバックスタックから取り出してからDへ遷移します。
もしバックスタックに存在しないrouteをしてした場合はオプションは無視されます。
popUpTo / inclusive
popUpTo
には更に inclusive
のオプションがあります。
navController.navigate("screen_d") {
popUpTo("screen_a") {
inclusive = true
}
}
inclusive
をtrueにすると、指定したrouteも含めてバックスタックから取り出されます。
saveState / restoreState
次に saveState
と restoreState
ですが、結構ややこしいです。FragmentのMultiple back stacksと同じものになります。
バックスタックから取り出した画面の状態を保存しておき、あとから復元できるようにしてくれます。
注意としては remember
のものは復元できません。 ViewModel
か rememberSaveable
のものが復元されます。
まずは popUpTo
で saveState
をオプション使います。
navController.navigate("screen_d") {
popUpTo("screen_a") {
saveState = true
}
}
saveState
をtrueにすると、バックスタックから取り出される画面の状態が保存されます。
このあとに restoreState
を使って復元します。
navController.navigate("screen_a") {
restoreState = true
}
ここでややこしいのが、 navigate
の宛先です。これは popUpTo
のときに inclusive
がtrueかfalseかで変わってきます。
inclusive
がfalseのときは、上の例だとAとBとその親を navigate
の宛先に指定すると状態が復元できす。親というのはNested Navigationの場合のみ使えます。
上の例で popUpTo
のときに inclusive
もtrueにした場合は、 restoreState
の navigate
の宛先はAだけが使用できます。
もし、それ以外の宛先を指定した場合は通常の画面遷移と同様の挙動になります。
また、 restoreState
では一度しか復元できません。