Navigation ComposeのNavOptions

Kenji Abe
May 3, 2022

--

Photo by Chris Lawton on Unsplash

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

次に saveStaterestoreState ですが、結構ややこしいです。FragmentのMultiple back stacksと同じものになります。

バックスタックから取り出した画面の状態を保存しておき、あとから復元できるようにしてくれます。
注意としては remember のものは復元できません。 ViewModelrememberSaveable のものが復元されます。

まずは popUpTosaveState をオプション使います。

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にした場合は、 restoreStatenavigate の宛先はAだけが使用できます。

もし、それ以外の宛先を指定した場合は通常の画面遷移と同様の挙動になります。

また、 restoreState では一度しか復元できません。

参考

--

--

Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO