NavigationUI を使用して UI コンポーネントを NavController に接続する

Navigation コンポーネントには、NavigationUI クラスがあります。このクラスには、トップ アプリバーやナビゲーション ドロワー、ボトム ナビゲーションを使用してナビゲーションを管理する静的メソッドが含まれています。

トップ アプリバー

トップ アプリバーは、アプリの上部に沿って同じ場所に配置され、現在の画面に基づく情報やアクションを表示します。

トップ アプリバーが表示されている画面
図 1. トップ アプリバーが表示されている画面

NavigationUI には、ユーザーがアプリ内を移動したときにトップ アプリバー内のコンテンツを自動的に更新するメソッドが含まれています。たとえば、NavigationUI は、ナビゲーション グラフ内のデスティネーション ラベルを使用して、トップ アプリバーのタイトルを最新の状態に保ちます。

<navigation>
    <fragment ...
              android:label="Page title">
      ...
    </fragment>
</navigation>

NavigationUI を使用して以下で説明するようなトップ アプリバーの実装を行った場合、デスティネーションにアタッチするラベルは、ラベル内で {argName} 形式を使用することで、デスティネーションに提供される引数に基づいて自動的に入力されます。

NavigationUI は、以下のタイプのトップ アプリバーをサポートしています。

アプリバーの詳細については、アプリバーの設定をご覧ください。

AppBarConfiguration

NavigationUI は、AppBarConfiguration オブジェクトを使用して、アプリの表示領域の左上隅にあるナビゲーション ボタンの動作を管理します。ナビゲーション ボタンの動作は、ユーザーが「トップレベル デスティネーション」にいるかどうかで変わります。

トップレベル デスティネーションとは、互いに階層構造としての関係を持つデスティネーションの中で、ルートまたは最上位レベルにあるデスティネーションのことです。トップレベル デスティネーションでは、それよりも上位にデスティネーションがないため、トップ アプリバーに「上へ」ボタンが表示されません。デフォルトでは、アプリの開始デスティネーションがトップレベル デスティネーションになります。

ユーザーがトップレベル デスティネーションにいるとき、デスティネーションで DrawerLayout を使用している場合は、ナビゲーション ボタンがドロワー アイコン になります。デスティネーションで DrawerLayout を使用していない場合は、ナビゲーション ボタンが非表示になります。ユーザーが他のデスティネーションにいるときは、ナビゲーション ボタンが「上へ」ボタン になります。開始デスティネーションのみをトップレベル ナビゲーションとして使用するナビゲーション ボタンを設定するには、対象のナビゲーション グラフを渡して AppBarConfiguration オブジェクトを作成します。以下をご覧ください。

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph)

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(navController.getGraph()).build();

場合によっては、デフォルトの開始デスティネーションを使用する代わりに、複数のトップレベル デスティネーションの定義が必要となることもあります。このように、互いに階層構造としての関係がなく、それぞれが別々の関連デスティネーション群を持つような兄弟画面がある場合には、BottomNavigationView を使用するのが一般的です。そのような場合は、コンストラクタにデスティネーション ID のセットを渡します。以下をご覧ください。

Kotlin

val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.profile))

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(R.id.main, R.id.profile).build();

ツールバーを作成する

NavigationUI を使用してツールバーを作成するには、まず、メイン アクティビティ内でバーを定義します。以下をご覧ください。

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar" />
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

次に、メイン アクティビティの onCreate() メソッドから setupWithNavController() を呼び出します。次の例をご覧ください。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    findViewById<Toolbar>(R.id.toolbar)
        .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

ナビゲーション ボタンがすべてのデスティネーションに「上へ」ボタンとして表示されるように設定するには、AppBarConfiguration をビルドする際に、トップレベル デスティネーションのデスティネーション ID の空のセットを渡します。これはたとえば、すべてのデスティネーションで Toolbar に「上へ」ボタンを表示させる 2 つ目のアクティビティがある場合に便利です。それにより、バックスタックに他のデスティネーションがない場合、ユーザーは親アクティビティに戻ることができます。navigateUp() による処理が他にない場合は、setFallbackOnNavigateUpListener() を使用してフォールバック動作を制御できます。次の例をご覧ください。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(
        topLevelDestinationIds = setOf(),
        fallbackOnNavigateUpListener = ::onSupportNavigateUp
    )
    findViewById<Toolbar>(R.id.toolbar)
        .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder()
        .setFallbackOnNavigateUpListener(::onSupportNavigateUp)
        .build();
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

CollapsingToolbarLayout を組み込む

ツールバーに CollapsingToolbarLayout を組み込むには、まず、アクティビティ内でツールバーと周囲のレイアウトを定義します。以下をご覧ください。

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/tall_toolbar_height">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

次に、メイン アクティビティの onCreate メソッドから setupWithNavController() を呼び出します。以下をご覧ください。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout)
    val toolbar = findViewById<Toolbar>(R.id.toolbar)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    layout.setupWithNavController(toolbar, navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    CollapsingToolbarLayout layout = findViewById(R.id.collapsing_toolbar_layout);
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupWithNavController(layout, toolbar, navController, appBarConfiguration);
}

アクションバー

デフォルト アクションバーにナビゲーション サポートを追加するには、メイン アクティビティの onCreate() メソッドから setupActionBarWithNavController() を呼び出します。以下をご覧ください。AppBarConfiguration は、onSupportNavigateUp() をオーバーライドする際にも使用するため、onCreate() の外部で宣言する必要があります。

Kotlin

private lateinit var appBarConfiguration: AppBarConfiguration

...

override fun onCreate(savedInstanceState: Bundle?) {
    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
}

Java

AppBarConfiguration appBarConfiguration;

...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}

次に、「上へ」ナビゲーションを処理する onSupportNavigateUp() をオーバーライドします。

Kotlin

override fun onSupportNavigateUp(): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return navController.navigateUp(appBarConfiguration)
            || super.onSupportNavigateUp()
}

Java

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.navigateUp(navController, appBarConfiguration)
            || super.onSupportNavigateUp();
}

アプリバーの変化をサポートする

アプリ内のデスティネーション間でトップ アプリバーのレイアウトが大幅に変化しない場合は、アクティビティにトップ アプリバーを追加しても問題ありません。しかし、トップ アプリバーがデスティネーション間で大幅に変化する場合は、アクティビティからトップ アプリバーを削除し、各デスティネーション フラグメントでトップ アプリバーを定義することを検討してください。

たとえば、あるデスティネーションでは標準の Toolbar を使用し、別のデスティネーションでは AppBarLayout を使用してタブのある複雑なアプリバーを作成するとします(図 2 を参照)。

2 種類のトップ アプリバー(左は標準の toolbar、右は toolbar とタブがある appbarlayout)
図 2. 2 種類のアプリバー。左が標準の Toolbar。右が Toolbar とタブがある AppBarLayout

この例を NavigationUI を使用してデスティネーション フラグメントに実装するには、まず各フラグメント レイアウトにアプリバーを定義します。1 つ目は、標準ツールバーを使用するデスティネーション フラグメントです。

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        ... />
    ...
</LinearLayout>

2 つ目は、タブ付きのアプリバーを使用するデスティネーション フラグメントです。

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        ... />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            ... />

        <com.google.android.material.tabs.TabLayout
            ... />

    </com.google.android.material.appbar.AppBarLayout>
    ...
</LinearLayout>

ナビゲーションの構成ロジックは基本的にこれらのフラグメントでも同じですが、アクティビティから初期化するのではなく、各フラグメントの onViewCreated() メソッドから setupWithNavController() を呼び出す必要がある点が異なります。

Kotlin

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val navController = findNavController()
    val appBarConfiguration = AppBarConfiguration(navController.graph)

    view.findViewById<Toolbar>(R.id.toolbar)
            .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) {
    NavController navController = Navigation.findNavController(view);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = view.findViewById(R.id.toolbar);

    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

デスティネーションとメニュー項目を結び付ける

NavigationUI は、デスティネーションをメニュー方式の UI コンポーネントに結び付けるヘルパーも提供します。NavigationUI には onNavDestinationSelected() ヘルパー メソッドが含まれており、このヘルパー メソッドは、MenuItem と、関連付けられたデスティネーションをホストする NavController を受け取ります。MenuItemid がデスティネーションの id と一致すると、NavController は、そのデスティネーションへのナビゲーションを実行します。

たとえば、以下の XML スニペットの場合、メニュー項目とデスティネーションを定義する際、共通の id である details_page_fragment を使用しています。

<?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"
    ... >

    ...

    <fragment android:id="@+id/details_page_fragment"
         android:label="@string/details"
         android:name="com.example.android.myapp.DetailsFragment" />
</navigation>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    ...

    <item
        android:id="@+id/details_page_fragment"
        android:icon="@drawable/ic_details"
        android:title="@string/details" />
</menu>

たとえば、アクティビティの onCreateOptionsMenu() からメニューを追加した場合、メニュー項目をデスティネーションに関連付けるには、アクティビティの onOptionsItemSelected() をオーバーライドして onNavDestinationSelected() を呼び出すようにします。以下の例をご覧ください。

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.onNavDestinationSelected(item, navController)
            || super.onOptionsItemSelected(item);
}

以上の設定により、ユーザーが details_page_fragment メニュー項目をタップすると、同じ id を持つデスティネーションに自動的に移動するようになります。

ナビゲーション ドロワーを追加する

ナビゲーション ドロワーは、アプリのメイン ナビゲーション メニューを表示する UI パネルです。 ドロワーは、ユーザーがアプリバー内のドロワー アイコン()をタップしたときや、画面の左端からスワイプしたときに表示されます。

ナビゲーション メニューを表示している開いたドロワー
図 3. ナビゲーション メニューを表示している開いたドロワー。

ドロワー アイコンは、DrawerLayout を使用しているすべてのトップレベル デスティネーション上で表示されます。

ナビゲーション ドロワーを追加するには、まず、DrawerLayout をルートビューとして宣言します。DrawerLayout 内に、メイン UI コンテンツのレイアウトと、ナビゲーション ドロワーのコンテンツを格納する別のビューを追加します。

たとえば、下記のレイアウトの場合、2 つの子ビューを持つ DrawerLayout を使用しています。一方の子ビューは、メイン コンテンツを格納する NavHostFragment で、もう一方の子ビューは、ナビゲーション ドロワーのコンテンツ用の NavigationView です。

<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
    <androidx.fragment.app.FragmentContainerView
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <!-- Container for contents of drawer - use NavigationView to make configuration easier -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true" />

</androidx.drawerlayout.widget.DrawerLayout>

次に、DrawerLayoutAppBarConfiguration に渡して、ナビゲーション グラフに接続します。次の例をご覧ください。

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(navController.getGraph())
            .setDrawerLayout(drawerLayout)
            .build();

次に、メイン アクティビティ クラス内で、メイン アクティビティの onCreate() メソッドから setupWithNavController() を呼び出します。以下をご覧ください。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<NavigationView>(R.id.nav_view)
        .setupWithNavController(navController)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    NavigationView navView = findViewById(R.id.nav_view);
    NavigationUI.setupWithNavController(navView, navController);
}

Navigation 2.4.0-alpha01 以降では、setupWithNavController を使用すると、各メニュー項目の状態を保存、復元できます。

ボトム ナビゲーション

NavigationUI は、ボトム ナビゲーションも処理できます。ユーザーがメニュー項目を選択すると、NavController は、onNavDestinationSelected() を呼び出して、ボトム ナビゲーション バー内で選択されているアイテムを自動的に更新します。

ボトム ナビゲーション バー
図 4. ボトム ナビゲーション バー。

アプリ内にボトム ナビゲーション バーを作成するには、まず、メイン アクティビティ内でバーを定義します。以下をご覧ください。

<LinearLayout>
    ...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        app:menu="@menu/menu_bottom_nav" />
</LinearLayout>

次に、メイン アクティビティ クラス内で、メイン アクティビティの onCreate() メソッドから setupWithNavController() を呼び出します。以下をご覧ください。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<BottomNavigationView>(R.id.bottom_nav)
        .setupWithNavController(navController)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    NavigationUI.setupWithNavController(bottomNav, navController);
}

Navigation 2.4.0-alpha01 以降では、setupWithNavController を使用すると、各メニュー項目の状態を保存、復元できます。

ボトム ナビゲーションを含む包括的な例については、GitHub の Android アーキテクチャ コンポーネントの高機能ナビゲーション サンプルをご覧ください。

ナビゲーション イベントをリッスンする

デスティネーション間のナビゲーションは、主に NavController の操作によって実行されます。NavController は、NavHost のコンテンツを新しいデスティネーションに置き換える役割を担います。多くの場合、UI 要素(トップ アプリバーや、BottomNavigationBar のような永続的ナビゲーション コントロールなど)は、NavHost の外側に存在しており、デスティネーション間を移動する際に更新する必要があります。

NavController は、NavController現在のデスティネーションまたはその引数が変更されたときに呼び出される OnDestinationChangedListener インターフェースを提供します。新しいリスナーは、addOnDestinationChangedListener() メソッドを通じて登録できます。addOnDestinationChangedListener() を呼び出すときに、現在のデスティネーションが存在する場合は、すぐにリスナーに送信されます。

NavigationUI は、OnDestinationChangedListener を使用して、このような一般的な UI コンポーネントにナビゲーション認識機能を追加します。また、OnDestinationChangedListener を単独で使用して、カスタム UI やカスタム ビジネス ロジックにナビゲーション イベント認識機能を追加することもできます。

たとえば、アプリの一部の領域では表示し、他の領域では非表示にする一般的 UI 要素があるとします。独自の OnDestinationChangedListener を使用することで、ターゲット デスティネーションに基づいてこの UI 要素の表示 / 非表示を選択的に指定できます。次の例をご覧ください。

Kotlin

navController.addOnDestinationChangedListener { _, destination, _ ->
   if(destination.id == R.id.full_screen_destination) {
       toolbar.visibility = View.GONE
       bottomNavigationView.visibility = View.GONE
   } else {
       toolbar.visibility = View.VISIBLE
       bottomNavigationView.visibility = View.VISIBLE
   }
}

Java

navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
   @Override
   public void onDestinationChanged(@NonNull NavController controller,
           @NonNull NavDestination destination, @Nullable Bundle arguments) {
       if(destination.getId() == R.id.full_screen_destination) {
           toolbar.setVisibility(View.GONE);
           bottomNavigationView.setVisibility(View.GONE);
       } else {
           toolbar.setVisibility(View.VISIBLE);
           bottomNavigationView.setVisibility(View.VISIBLE);
       }
   }
});

引数ベースのリスナー

代わりの方法として、ナビゲーション グラフ内でデフォルト値を持つ引数を使用することもできます。この引数は、該当する UI コントローラが状態を更新するために使用できます。たとえば、上記の例のように OnDestinationChangedListener 内のロジックをデスティネーション ID に基づいて作成するのではなく、次のように NavGraph 内で引数を作成します。

<?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/navigation\_graph"
    app:startDestination="@id/fragmentOne">
    <fragment
        android:id="@+id/fragmentOne"
        android:name="com.example.android.navigation.FragmentOne"
        android:label="FragmentOne">
        <action
            android:id="@+id/action\_fragmentOne\_to\_fragmentTwo"
            app:destination="@id/fragmentTwo" />
    </fragment>
    <fragment
        android:id="@+id/fragmentTwo"
        android:name="com.example.android.navigation.FragmentTwo"
        android:label="FragmentTwo">
        <argument
            android:name="ShowAppBar"
            android:defaultValue="true" />
    </fragment>
</navigation>

この引数は、デスティネーションに移動するときに使用されるものではなく、defaultValue を使用してデスティネーションに追加の情報を渡す方法として使用されます。この場合、この値は、デスティネーションにいるときにアプリバーを表示するかどうかを示しています。

これで、次のように OnDestinationChangedListenerActivity に追加できます。

Kotlin

navController.addOnDestinationChangedListener { _, _, arguments ->
    appBar.isVisible = arguments?.getBoolean("ShowAppBar", false) == true
}

Java

navController.addOnDestinationChangedListener(
        new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(
                    @NonNull NavController controller,
                    @NonNull NavDestination destination,
                    @Nullable Bundle arguments
            ) {
                boolean showAppBar = false;
                if (arguments != null) {
                    showAppBar = arguments.getBoolean("ShowAppBar", false);
                }
                if(showAppBar) {
                    appBar.setVisibility(View.VISIBLE);
                } else {
                    appBar.setVisibility(View.GONE);
                }
            }
        }
);

NavController は、ナビゲーション デスティネーションが変更されるたびにこのコールバックを呼び出します。Activity は、コールバックで受け取った引数に基づいて、所有する UI コンポーネントの状態または可視性を更新できるようになりました。

このアプローチの利点として、Activity はナビゲーション グラフの引数のみを参照し、個々の Fragment の役割と責任については関知しないことが挙げられます。同様に、個々のフラグメントは、それに含まれる Activity とその所有する UI コンポーネントについては関知しません。

参考情報

ナビゲーションについて詳しくは、以下の参考情報をご確認ください。

サンプル

Codelab

ブログ投稿

動画