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

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

環境をセットアップする

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

Groovy

dependencies {
  def nav_version = "2.5.3"

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

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

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

  // Jetpack Compose Integration
  implementation "androidx.navigation:navigation-compose:$nav_version"
}

Kotlin

dependencies {
  val nav_version = "2.5.3"

  // 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")

  // Feature module Support
  implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")

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

  // Jetpack Compose Integration
  implementation("androidx.navigation:navigation-compose:$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"?>
<androidx.constraintlayout.widget.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
        .../>

    <androidx.fragment.app.FragmentContainerView
        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
        .../>

</androidx.constraintlayout.widget.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] フィールド - ユーザーが読むことのできる形式でデスティネーションの名前が表示されます。これは UI に表示されることがあります(setupWithNavController() を使用して NavGraphToolbar に接続する場合など)。そのため、この値にはリソース文字列を使用することをおすすめします。
  • [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="@string/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="@string/label_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="@string/label_blank_2"
            tools:layout="@layout/fragment_blank_fragment2" />
    </navigation>
    

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

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

Kotlin:

Java:

FragmentContainerView を使用して NavHostFragment を作成する場合、または FragmentTransaction からアクティビティに NavHostFragment を手動で追加する場合、Navigation.findNavController(Activity, @IdRes int) からアクティビティの onCreate()NavController を取得しようとするとエラーになります。NavHostFragment から直接 NavController を取得してください。

Kotlin

val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

Java

NavHostFragment navHostFragment =
        (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

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

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

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

Groovy

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

Kotlin

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

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

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

Groovy

plugins {
  id 'androidx.navigation.safeargs'
}

Kotlin

plugins {
    id("androidx.navigation.safeargs")
}

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

Groovy

plugins {
  id 'androidx.navigation.safeargs.kotlin'
}

Kotlin

plugins {
    id("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 を使用してタイプセーフにデータを渡すをご覧ください。

詳細情報

Navigation に関する問題を発見した場合は、以下のいずれかのチャネルを通してフィードバックをお送りください。

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