Navigation コンポーネントは、ナビゲーション グラフを使用してアプリのナビゲーションを管理します。ナビゲーション グラフは、アプリ内のすべてのデスティネーションとともに、ユーザーがデスティネーション間を移動する際にたどる可能性がある論理的な道筋(アクション)を格納するリソース ファイルです。Android Studio の Navigation Editor を使用して、アプリのナビゲーション グラフを管理できます。
このトピックでは、アプリのナビゲーション グラフを設計する際のベスト プラクティスと推奨事項について説明します。
トップレベル ナビゲーション グラフ
アプリのトップレベル ナビゲーション グラフは、ユーザーがアプリを起動したときに最初に表示される開始デスティネーションから始まり、ユーザーがアプリ内を移動する際に表示されるすべてのデスティネーションを含む必要があります。
図 1. トップレベル ナビゲーション グラフ
ネストグラフ
一般的に、アプリ内のログインフロー、ウィザード、その他のサブフローは、ネストされたナビゲーション グラフとして表現するのが最も適切です。このように自己完結型のサブナビゲーション フローをネストすることにより、アプリの UI のメインフローの把握と管理が容易になります。また、ネストグラフは再利用可能です。さらに、一定レベルのカプセル化も実現できます。ネストグラフの外部にあるデスティネーションは、ネストグラフの内部にあるデスティネーションに直接アクセスすることができません。代わりに、navigate()
を使用して、ネストグラフ自体にアクセスする必要があります。ネストグラフの内部ロジックは、グラフの残りの部分に影響を与えることなく変更できます。
図 1 のトップレベル ナビゲーション グラフの例で、ユーザーがアプリを初めて起動したときに限り、title_screen 画面と register 画面を表示したいとします。さらに、ユーザー情報を保存して、次回以降のアプリの起動時には、直接 match 画面にユーザーを誘導するとします。ベスト プラクティスとしては、match 画面をトップレベル ナビゲーション グラフの開始デスティネーションに設定し、title_screen 画面と register 画面をネストグラフに移動するのが適切です。図 2 をご覧ください。
図 2. ネストグラフが追加されたトップレベル ナビゲーション グラフ
match 画面が起動したら、登録済みユーザーがいるかどうかをチェックします。ユーザーが登録されていない場合は、ユーザーを register 画面に誘導します。条件付きナビゲーション シナリオの詳細については、条件付きナビゲーションをご覧ください。
グラフ構造をモジュール化するもう 1 つの方法は、親ナビゲーション グラフ内の <include>
要素を介して、別のグラフを子グラフとして組み込むことです。この方法では、組み込まれる側のグラフを独立したモジュールまたはプロジェクト内で定義できるため、最大限の再利用可能性を実現できます。
ライブラリ モジュール間のナビゲーション
ナビゲーション グラフを格納するライブラリ モジュールにアプリが依存している場合は、<include>
要素を使用して、それらのナビゲーション グラフを参照できます。
詳しくは、マルチモジュール プロジェクトのナビゲーションに関するベスト プラクティスをご覧ください。
グローバル アクション
アプリのデスティネーションに到達できるパスが複数ある場合、そのデスティネーションに移動するためのグローバル アクションを定義する必要があります。グローバル アクションを利用すると、どこからでも対象のデスティネーションに移動できるようになります。
グローバル アクションを上記のライブラリ モジュール サンプルに適用してみましょう。このサンプルでは、results_winner デスティネーションと game_over デスティネーションの両方に対して同じアクションが定義されています。この共通アクションを単一のグローバル アクションとして抽出し、両方のデスティネーションから参照するようにします。以下の例をご覧ください。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/in_game_nav_graph"
app:startDestination="@id/in_game">
<!-- Action back to destination which launched into this in_game_nav_graph-->
<action android:id="@+id/action_pop_out_of_game"
app:popUpTo="@id/in_game_nav_graph"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/in_game"
android:name="com.example.android.gamemodule.InGame"
android:label="Game">
<action
android:id="@+id/action_in_game_to_resultsWinner"
app:destination="@id/results_winner" />
<action
android:id="@+id/action_in_game_to_gameOver"
app:destination="@id/game_over" />
</fragment>
<fragment
android:id="@+id/results_winner"
android:name="com.example.android.gamemodule.ResultsWinner" />
<fragment
android:id="@+id/game_over"
android:name="com.example.android.gamemodule.GameOver"
android:label="fragment_game_over"
tools:layout="@layout/fragment_game_over" />
</navigation>
フラグメント内でグローバル アクションを使用する方法の詳細と例については、ナビゲーション ドキュメントのグローバル アクションをご覧ください。