複数のバックスタックをサポートする

Navigation コンポーネントは、Android オペレーティング システムと連携し、ユーザーのアプリ内での移動に応じてバックスタックを保持します。複数のバックスタックを同時に保持することにより、ユーザーがバックスタック間を行き来できて便利になる場合があります。たとえば、ボトム ナビゲーションまたはナビゲーション ドロワーを使用するアプリの場合、複数のバックスタックをサポートすることで、ユーザーはアプリ内の複数のフローを、それぞれの中での場所を維持したまま、自由に切り替えられるようになります。

Navigation コンポーネントには、複数のバックスタックをサポートする API が用意されています。これらの API は、ナビゲーション グラフを使用してデスティネーションの状態を保存、復元する仕組みになっています。NavigationUI クラスには、これを自動的に処理するメソッドが含まれています。また、その基盤となる API を手動で利用すれば、よりカスタマイズした実装を行うこともできます。

NavigationUI を使用してサポートを自動的に実装する

NavigationUI クラスには、ユーザーのメニュー項目間の移動に応じてメニュー項目の状態の保存と復元を自動的に行う API が含まれています。これらの API は、次の場合に複数のバックスタックのサポートをデフォルトで実装します。

これらの API を使用すれば、それ以上のコード変更をせずに複数のバックスタックのサポートを実装できます。アプリで複数のバックスタックをサポートする場合に推奨される方法です。

基盤となる API を使用してサポートを手動で実装する

NavigationUI の要素では要件を満たせない場合、Navigation コンポーネントが提供する別の API サーフェスから、基盤となる API を使用してバックスタックの保存、復元を行えます。

Navigation XML 内で、ナビゲーション グラフの <action> 要素に app:popUpToSaveState 属性を設定して、アクションが app:popUpTo でポップしたデスティネーションの状態を保存するよう指定できます。また、app:restoreState 属性を設定することで、app:destination 属性で定義したデスティネーションについて、保存されている状態を復元するよう指定できます。

これらの属性を使用して、複数のバックスタックをサポートできます。ナビゲーション アクションがユーザーをあるバックスタックから別のバックスタックに移動する必要がある場合は、対応する <action> 要素で app:popUpToSaveStateapp: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 クラスを使用すると、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 コンポーネントにおける複数のバックスタックのサポートについて詳しくは、以下の参考情報をご覧ください。

ブログ投稿

サンプル