6 月 3 日の「#Android11: The Beta Launch Show」にぜひご参加ください。

Navigation コンポーネント スタートガイド

このトピックでは、Navigation コンポーネントのセットアップ方法や使用方法について説明します。Navigation コンポーネントの概要については、ナビゲーションの概要をご覧ください。

環境をセットアップする

プロジェクトにナビゲーション サポートを組み込むには、アプリの build.gradle ファイルに以下の依存関係を追加します。

    dependencies {
      def nav_version = "2.3.0-alpha05"

      // Java language implementation
      implementation "androidx.navigation:navigation-fragment:$nav_version"
      implementation "androidx.navigation:navigation-ui:$nav_version"

      // Kotlin
      implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
      implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

      // Dynamic Feature Module Support
      implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

      // Testing Navigation
      androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
    }
    

他のアーキテクチャ コンポーネントをプロジェクトに追加する方法については、プロジェクトにコンポーネントを追加するをご覧ください。

ナビゲーション グラフを作成する

ナビゲーションとは、アプリ内の「デスティネーション」(ユーザーがアプリ内で移動できる場所)の間の移動のことを指します。デスティネーションは、「アクション」を通じて接続されます。

「ナビゲーション グラフ」は、すべてのデスティネーションとアクションを格納するリソース ファイルです。このグラフは、アプリ内のすべてのナビゲーション パスを示します。

5 つのアクションによって接続された 6 つのデスティネーションを含むサンプルアプリのナビゲーション グラフの視覚的表現を図 1 に示します。各デスティネーションはプレビュー サムネイルで表現され、接続アクションは矢印で表現されます。この矢印は、ユーザーがデスティネーション間を移動する方法を示します。

図 1: 5 つのアクションを通じて接続された 6 つのデスティネーションのプレビューを表示するナビゲーション グラフ
  1. 「デスティネーション」は、アプリ内のさまざまなコンテンツ領域を示します。
  2. 「アクション」は、デスティネーション間の論理接続を示し、ユーザーが移動可能なパスを表現します。

プロジェクトにナビゲーション グラフを追加する手順は次のとおりです。

  1. [Project] ウィンドウで、res ディレクトリを右クリックして、[New] > [Android Resource File] を選択します。[New Resource File] ダイアログが表示されます。
  2. [File name] フィールドに、「nav_graph」などの名前を入力します。
  3. [Resource type] プルダウン リストから [Navigation] を選択して、[OK] をクリックします。

初めてナビゲーション グラフを追加したときに、Android Studio によって、res ディレクトリ内に navigation リソース ディレクトリが作成されます。このディレクトリには、ナビゲーション グラフ リソース ファイル(nav_graph.xml など)が格納されます。

グラフを追加すると、Android Studio は Navigation Editor 内でグラフを開きます。Navigation Editor 内では、ナビゲーション グラフを視覚的に編集することも、基盤となる XML を直接編集することもできます。

図 2: Navigation Editor
  1. [Destinations] パネル: ナビゲーション ホストと、現在 Graph Editor 内にあるすべてのデスティネーションをリスト表示します。
  2. Graph Editor: ナビゲーション グラフを視覚的に表現します。視覚的表現を示す [Design] ビューと、基盤 XML 表現を示す [Text] ビューを切り替えることができます。
  3. Attributes: ナビゲーション グラフ内で現在選択されているアイテムの属性を表示します。

[Text] タブをクリックすると、対応する XML が表示されます。XML は次のスニペットのようになります。

<?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/nav_graph">

    </navigation>
    

<navigation> 要素は、ナビゲーション グラフのルート要素です。グラフにデスティネーションと接続アクションを追加した場合、対応する <destination> 要素と <action> 要素が子要素として表示されます。ネストされたグラフがある場合は、子 <navigation> 要素として表示されます。

NavHost をアクティビティに追加する

Navigation コンポーネントの中核部分の一つに、「ナビゲーション ホスト」があります。ナビゲーション ホストは空のコンテナであり、ユーザーがアプリ内を移動するたびに、そのコンテナ内でデスティネーションが入れ替わります。

ナビゲーション ホストは、NavHost から導出する必要があります。Navigation コンポーネントのデフォルト NavHost 実装である NavHostFragment は、フラグメント デスティネーションの切り替えを処理します。

XML で NavHostFragment を追加する

アプリのメイン アクティビティに NavHostFragment を組み込んだ XML の例を以下に示します。

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.appcompat.widget.Toolbar
            .../>

        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"

            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" />

        <com.google.android.material.bottomnavigation.BottomNavigationView
            .../>

    </android.support.constraint.ConstraintLayout>
    

注:

  • android:name 属性には、NavHost 実装のクラス名が格納されます。
  • app:navGraph 属性は、NavHostFragment をナビゲーション グラフに関連付けます。ナビゲーション グラフは、ユーザーが移動可能なこの NavHostFragment 内のすべてのデスティネーションを指定します。
  • app:defaultNavHost="true" 属性を使用すると、NavHostFragment が、システムの [戻る] ボタンをインターセプトできるようになります。1 つの NavHost だけに限り、デフォルトとして指定できます。1 つのレイアウト(たとえば、2 ペイン レイアウト)内に複数のホストがある場合は、1 つの NavHost だけをデフォルトとして指定してください。

また、Layout Editor を使用して、アクティビティに NavHostFragment を追加することもできます。手順は次のとおりです。

  1. プロジェクト ファイルのリスト内で、アクティビティのレイアウト XML ファイルをダブルクリックして、Layout Editor で開きます。
  2. [Palette] パネルで、[Containers] カテゴリを選択するか、「NavHostFragment」を検索します。
  3. NavHostFragment ビューをアクティビティにドラッグします。
  4. 表示された [Navigation Graphs] ダイアログで、この NavHostFragment に関連付けるナビゲーション グラフを選択して、[OK] をクリックします。

ナビゲーション グラフにデスティネーションを追加する

既存のフラグメントやアクティビティからデスティネーションを作成できます。また、Navigation Editor を使用して、新しいデスティネーションを作成したり、後でフラグメントやアクティビティに置き換えるプレースホルダを作成したりすることもできます。

この例では、新しいデスティネーションを作成します。Navigation Editor を使用して新しいデスティネーションを追加する手順は次のとおりです。

  1. Navigation Editor 内で、[New Destination] アイコン をクリックして、[Create new destination] をクリックします。
  2. 表示された [New Android Component] ダイアログで、フラグメントを作成します。フラグメントの詳細については、フラグメントをご覧ください。

Navigation Editor に戻ると、作成したデスティネーションが Android Studio によってグラフに追加されています。

デスティネーションとプレースホルダ デスティネーションの例を図 3 に示します。

図 3: デスティネーションとプレースホルダ

ナビゲーション グラフにデスティネーションを追加する他の方法については、デスティネーションを作成するをご覧ください。

デスティネーションの構造

デスティネーションをクリックして選択し、[Attributes] パネルで以下の属性を確認してください。

  • [Type] フィールド - デスティネーションの実装タイプがフラグメントなのか、アクティビティなのか、ソースコード内の他のカスタムクラスなのかを示します。
  • [Label] フィールド - デスティネーションの XML レイアウト ファイルの名前が表示されます。
  • [ID] フィールド - コード内でデスティネーションを参照する際に使用するデスティネーション ID が表示されます。
  • [Class] プルダウン - デスティネーションに関連付けられているクラスの名前が表示されます。このプルダウンをクリックすると、対象のクラスを別のデスティネーション タイプに変更できます。

[Text] タブをクリックすると、ナビゲーション グラフの XML ビューが表示されます。XML には、デスティネーションに対して同じ id 属性、name 属性、label 属性、layout 属性が組み込まれています。以下をご覧ください。

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        app:startDestination="@id/blankFragment">
        <fragment
            android:id="@+id/blankFragment"
            android:name="com.example.cashdog.cashdog.BlankFragment"
            android:label="Blank"
            tools:layout="@layout/fragment_blank" />
    </navigation>
    

画面を開始デスティネーションとして指定する

開始デスティネーションは、ユーザーがアプリを開いたときに最初に表示される画面であり、アプリを終了する際に最後に表示される画面でもあります。Navigation Editor は、ホームアイコン を使用して開始デスティネーションを示します。

すべてのデスティネーションを設定したら、開始デスティネーションを選択します。手順は次のとおりです。

  1. [Design] タブで、デスティネーションをクリックしてハイライト表示します。

  2. [Assign start destination] ボタン をクリックします。あるいは、デスティネーションを右クリックして、[Set as Start Destination] をクリックします。

デスティネーションを接続する

アクションは、デスティネーション間の論理接続です。アクションは、ナビゲーション グラフ内で矢印として表示されます。アクションは通常、デスティネーションとデスティネーションを接続しますが、アプリ内の任意の場所から特定のデスティネーションに移動するためのグローバル アクションを作成することもできます。

アクションを使用すると、ユーザーがアプリ内を移動する際に通過可能なさまざまなパスを表現できます。ただし、実際にデスティネーションに移動するには、そのナビゲーションを実行するコードを記述する必要があります。この点については、下記のデスティネーションに移動するをご覧ください。

Navigation Editor を使用して、2 つのデスティネーションを接続できます。手順は次のとおりです。

  1. [Design] タブで、ユーザーの移動元になるデスティネーションの右側にカーソルを合わせます。図 4 に示すように、デスティネーションの右側に円が表示されます。

    図 4: アクション接続サークルが付いたデスティネーション
  2. クリックしたまま、ユーザーの移動先となるデスティネーションまでカーソルをドラッグしてリリースします。図 5 に示すように、2 つのデスティネーション間を結ぶ線がアクションとして表示されます。

    図 5: アクションを使用してデスティネーションを接続する
  3. 矢印をクリックすると、アクションがハイライト表示されます。次の属性が [Attributes] パネルに表示されます。

    • [Type] フィールド - 「Action」と表示されます。
    • [ID] フィールド - アクションの ID が表示されます。
    • [Destination] フィールド - デスティネーション フラグメントまたはデスティネーション アクティビティの ID が表示されます。
  4. [Text] タブをクリックして、XML ビューに切り替えます。アクション要素がソース デスティネーションに追加されています。アクション要素には、ID 属性と、移動先のデスティネーションの ID を格納するデスティネーション属性があります。以下の例をご覧ください。

    <?xml version="1.0" encoding="utf-8"?>
        <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:android="http://schemas.android.com/apk/res/android"
            app:startDestination="@id/blankFragment">
            <fragment
                android:id="@+id/blankFragment"
                android:name="com.example.cashdog.cashdog.BlankFragment"
                android:label="fragment_blank"
                tools:layout="@layout/fragment_blank" >
                <action
                    android:id="@+id/action_blankFragment_to_blankFragment2"
                    app:destination="@id/blankFragment2" />
            </fragment>
            <fragment
                android:id="@+id/blankFragment2"
                android:name="com.example.cashdog.cashdog.BlankFragment2"
                android:label="fragment_blank_fragment2"
                tools:layout="@layout/fragment_blank_fragment2" />
        </navigation>
        

ナビゲーション グラフ内で、アクションは <action> 要素で表現されます。アクションは少なくとも、自身の ID と、ユーザーの移動先となるデスティネーションの ID を格納します。

デスティネーションへの移動は、NavHost 内でアプリ ナビゲーションを管理するオブジェクトである NavController を使用して実行されます。各 NavHost は、それぞれ独自の NavController を持ちます。NavController を取得するには、以下のいずれかの方法を使用します。

Kotlin:

Java:

Safe Args を使用してタイプセーフな実装にする

デスティネーション間を移動する際は、Safe Args Gradle プラグインを使用することをおすすめします。このプラグインは、デスティネーション間でタイプセーフなナビゲーションや引数の受け渡しを可能にするシンプルなオブジェクトとビルダークラスを生成します。

Safe Args をプロジェクトに追加するには、最上位の build.gradle ファイルに次の classpath を含めます。

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.3.0-alpha06"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

また、使用可能な 2 つのプラグインのいずれかを適用する必要があります。

Java モジュールまたは Java と Kotlin の混合モジュールに適した Java 言語コードを生成するには、アプリまたはモジュールbuild.gradle ファイルに次の行を追加します。

apply plugin: "androidx.navigation.safeargs"

Kotlin のみのモジュールに適した Kotlin コードを生成するには、次の行を追加します。

apply plugin: "androidx.navigation.safeargs.kotlin"

AndroidX への移行にあるとおり、gradle.properties ファイルandroid.useAndroidX=true が必要です。

Safe Args を有効にすると、このプラグインによって、定義した各アクションのクラスとメソッドを格納するコードが生成されます。各アクションに対し、Safe Args は、アクションの発生元となる送信側デスティネーションごとにクラスを生成します。生成されるクラス名は、送信側デスティネーションのクラス名に「Directions」という語を組み合わせたものになります。たとえば、送信側デスティネーションが「SpecifyAmountFragment」という名前の場合、「SpecifyAmountFragmentDirections」という名前のクラスが作成されます。生成されるクラスには、送信側デスティネーション内で定義されている各アクション用の静的メソッドが格納されます。このメソッドは、定義済みのアクション パラメータを引数として受け取り、NavDirections オブジェクトを返します。このオブジェクトは navigate() に渡すことができます。

たとえば、送信側デスティネーション「SpecifyAmountFragment」を受信側デスティネーション「ConfirmationFragment」に接続する単一のアクションを持つナビゲーション グラフがあるとします。

Safe Args は、NavDirections オブジェクトを返す単一メソッド「actionSpecifyAmountFragmentToConfirmationFragment()」を持つ SpecifyAmountFragmentDirections クラスを生成します。返された NavDirections オブジェクトは、navigate() に直接渡すことができます。以下の例をご覧ください。

Kotlin

    override fun onClick(view: View) {
        val action =
            SpecifyAmountFragmentDirections
                .actionSpecifyAmountFragmentToConfirmationFragment()
        view.findNavController().navigate(action)
    }
    

Java

    @Override
    public void onClick(View view) {
        NavDirections action =
            SpecifyAmountFragmentDirections
                .actionSpecifyAmountFragmentToConfirmationFragment();
        Navigation.findNavController(view).navigate(action);
    }
    

Safe Args を使用してデスティネーション間でデータを渡す方法については、Safe Args を使用してタイプセーフにデータを渡すをご覧ください。

詳細情報

ナビゲーションに関して問題が発生した場合は、以下のいずれかのチャネルからフィードバックを送信してください。

バグレポート内で最も有益な情報を提供する方法については、以下のリンクをご覧ください。