📱
NavGraphが分割されたFragmentに対して直接遷移したい(Navigation DeepLink)
背景
- メニュー画面とメインフローでnavGraphを分割した
- しかし、その後メインフローでメニューの詳細機能へのショートカットボタンが追加された
- メニュー画面を経由させずにメニューの詳細機能画面へ遷移したい
- でも単にnavGraphをincludeするだけだとメニュー画面(startDestination)にしか遷移できない
方法
NavigationのDeepLinkを利用する
実装
1. deeplinkのタグを遷移先のFragmentに追加する
遷移先navigation.xml
<fragment
android:id="@+id/sennisakiFragment"
android:name="example.SennisakiFragment"
android:label="SennisakiFragment">
<deepLink
android:id="@+id/to_sennisaki"
app:uri="example://menu/sennisaki" />
</fragment>
2. 遷移元のnavGraphに遷移先のnavGraphをincludeする
遷移元navigation.xml
....
<include app:graph="@navigation/遷移先navigation" />
</navigation>
3. ショートカットタップ時にDeepLinkする
// 別にNavDeepLinkRequestを作らなくても、navController.navigate(Uri.parse("example://menu/sennisaki"))でも大丈夫
val navDeepLinkRequest = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("example://menu/sennisaki"))
.build()
// どこに戻ってくるかとか、singleTopでしたいとかを設定したいときはnavOptionsを利用する
val navOptions = NavOptions.Builder()
.setPopUpTo(R.id.sennimotoFragment, false)
.build()
findNavController().navigate(navDeepLinkRequest, navOptions)
これでOK。
補足
- 利用するnavControllerはもちろんincludeしたnavGraphのnavControllerを使う
- もしnavGraphの中のFragmentがさらにnavGraphを持っていた場合などは以下のようにfindFragmentByIdとかでとってくると良いかも。
childFragmentManager.findFragmentById(R.id.nakano_nav_host)?.let {
val navController = NavHostFragment.findNavController(it)
navController.navigate(navDeepLinkRequest, navOptions)
}
感想
情報が少なすぎて半日かかったよ。。
Discussion