Navigation コンポーネントは、Android オペレーティング システムと連携し、ユーザーのアプリ内での移動に応じてバックスタックを保持します。複数のバックスタックを同時に保持することにより、ユーザーがバックスタック間を行き来できて便利になる場合があります。たとえば、ボトム ナビゲーションまたはナビゲーション ドロワーを使用するアプリの場合、複数のバックスタックをサポートすることで、ユーザーはアプリ内の複数のフローを、それぞれの中での場所を維持したまま、自由に切り替えられるようになります。
Navigation コンポーネントには、複数のバックスタックをサポートする API が用意されています。これらの API は、ナビゲーション グラフを使用してデスティネーションの状態を保存、復元する仕組みになっています。NavigationUI
クラスには、これを自動的に処理するメソッドが含まれています。また、その基盤となる API を手動で利用すれば、よりカスタマイズした実装を行うこともできます。
NavigationUI を使用してサポートを自動的に実装する
NavigationUI
クラスには、ユーザーのメニュー項目間の移動に応じてメニュー項目の状態の保存と復元を自動的に行う API が含まれています。これらの API は、次の場合に複数のバックスタックのサポートをデフォルトで実装します。
- ナビゲーション ドロワーを追加するまたはボトム ナビゲーションで説明されているとおり、
setupWithNavController()
の適切なオーバーロードを使用して、NavigationView
またはBottomNavigationView
のインスタンスをNavController
インスタンスに関連付ける場合。 onNavDestinationSelected()
を使用して、NavController
インスタンスがホストするデスティネーションに結び付けられたカスタム ナビゲーション メニュー UI を作成する場合。
これらの API を使用すれば、それ以上のコード変更をせずに複数のバックスタックのサポートを実装できます。アプリで複数のバックスタックをサポートする場合に推奨される方法です。
基盤となる API を使用してサポートを手動で実装する
NavigationUI
の要素では要件を満たせない場合、Navigation コンポーネントが提供する別の API サーフェスから、基盤となる API を使用してバックスタックの保存、復元を行えます。
Navigation XML
Navigation XML 内で、ナビゲーション グラフの <action>
要素に app:popUpToSaveState
属性を設定して、アクションが app:popUpTo
でポップしたデスティネーションの状態を保存するよう指定できます。また、app:restoreState
属性を設定することで、app:destination
属性で定義したデスティネーションについて、保存されている状態を復元するよう指定できます。
これらの属性を使用して、複数のバックスタックをサポートできます。ナビゲーション アクションがユーザーをあるバックスタックから別のバックスタックに移動する必要がある場合は、対応する <action>
要素で app:popUpToSaveState
と app:restoreState
の両方を true
に設定します。そうすることで、このアクションは現在のバックスタックの状態を保存すると同時に、以前に保存したデスティネーションのバックスタックの状態も復元します(存在する場合)。
両方の属性を使用するアクションの例を次に示します。
<action
android:id=”@+id/swap_stack”
app:destination=”@id/second_stack”
app:restoreState=”true”
app:popUpTo=”@id/first_stack_start_destination”
app:popUpToSaveState=”true” />
NavOptions
NavOptions
クラスを使用すると、NavController
を使用した移動の際に、特別なナビゲーション オプションを渡してバックスタックの保存、復元を行えます。これは、NavOptions
インスタンスの作成に Kotlin DSL を使用する場合、NavOptions.Builder
を使用する場合のどちらにも当てはまります。
Kotlin
// Use the navigate() method that takes a navOptions DSL Builder navController.navigate(selectedBottomNavRoute) { launchSingleTop = true restoreState = true popUpTo(navController.graph.findStartDestination().id) { saveState = true } }
Java
NavOptions navOptions = new NavOptions.Builder() .setLaunchSingleTop(true) .setRestoreState(true) .setPopUpTo(NavGraph.findStartDestination(navController.getGraph()).getId(), false, // inclusive true) // saveState .build(); navController.navigate(selectedBottomNavId, null, navOptions);
ナビゲーション オプションを渡す方法については、プログラムで NavOptions を適用する方法についての説明をご覧ください。
参考情報
Navigation コンポーネントにおける複数のバックスタックのサポートについて詳しくは、以下の参考情報をご覧ください。
ブログ投稿
- Medium の MAD Skills: Navigation multiple back stacks
- Medium の Navigation: Multiple Back Stacks deep dive
サンプル
- GitHub の Now in Android app
- GitHub の Jetnews
- GitHub の Jetsnack