【Kotlin】Navigation(AAC)とUIComponentを連携する

#記事を移動しました。
https://zenn.dev/dd_sho/articles/7d849ffa8c7829
今後は上記の記事で更新します。（2021/10/03）

`NavigationUI` クラスを使うことでAACのNavigationと後述するUIComponentを簡単に連携されることができるので備忘録として記事にします。
[公式リファレンスはこちら](https://developer.android.com/guide/navigation/navigation-ui)

## NavigationUIクラスとは

NavigationUIクラスには、
`Top App Bar`、`Navigation Drawer`、`Bottom Navigation`とNavigationを連携するためのメソッドが用意されている。

### `Top App Bar`
![mio-design-assets-1ekbPWQqJ5sMNvJ0om7XelfzOhaWMaeyM-topappbars-howtouse-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139470/812b29be-4893-9748-9b98-f25dd05a11ae.png)

### `Navigation Drawer`
![mio-design-assets-1JkhpaOoDpFrCKLLoZMmbfiBMofzKS-lY-usage-do.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139470/1713d406-058d-063f-6662-127301b06a02.png)

### `Bottom Navigation`
![mio-design-assets-1h5m0BGM_LfXii-6hO4JisEM0bcWvG0Gl-bottomnav-usage-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139470/2442a632-380d-6b70-03b5-e91d05b8c9b6.png)

画像は公式サイトのものをお借りしました。
[マテリアル・デザイン](https://material.io)

## Top App Barとの連携

できること
・戻るボタン（←）の表示
・画面遷移時にタイトルをNavigationのグラフで各画面に設定したlabelで自動更新する

連携可能なTop App Bar

- **ToolBar**
- **CollapsingToolBarLayout**
- **ActionBar**

Navigationボタンの挙動を管理するために`AppBarConfiguration`クラスを利用する。
デフォルトではNavigationグラフで画面遷移の一番最初の画面ではNavigationボタンは表示されず、
他の画面に遷移したら戻るボタンが表示される。
以下のようにインスタンスを生成する。

```kotlin:
val appBarConfiguration = AppBarConfiguration(navController.graph)
```

画面遷移の一番最初の画面を指定する場合は、

```kotlin:
val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.android))
```

### ToolBar
ActivityのonCreate()メソッド内で

```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)
}
```

※ToolBarを使う時は、Navigationが自動的にクリックイベントをハンドルするので
onSupportNavigateUp()をオーバーライドする必要はない。


### CollapsingToolbarLayout
ActivityのonCreate()メソッド内で

```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 navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    layout.setupWithNavController(toolbar, navController, appBarConfiguration)
}
```

### Action Bar
①ActivityのonCreate()メソッド内で

```kotlin:

private lateinit var appBarConfiguration: AppBarConfiguration

// ・・・

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

    // ・・・

    val navController = findNavController(R.id.nav_host_fragment)
    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
}
```

②onSupportNavigateUp()メソッドをオーバーライドする。（戻るボタンが動作する）

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

### MenuItemと画面を紐付ける

①Navigationグラフのfragmentに割り振るidと紐づけるMenuItemのidを一致させる。
②ActivityのonOptionsItemSelected()をオーバーライドし、onNavDestinationSelected()を呼び出す。

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

## Navigation Drawerとの連携

ActivityのonCreate()内で、

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

    // ・・・

    val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
    val navController = findNavController(R.id.nav_host_fragment)
    findViewById<NavigationView>(R.id.nav_view)
        .setupWithNavController(navController)
}
```

※Top App Barがdrawerアイコンと戻るボタンの切り替えを自動でやってくれるのでActionBarDrawerToggleクラスを使う必要はない。

## Bottom Navigationとの連携

できること
　Bottomアイテムが選択されるとNavControllerはonNavDestinationSelected()を呼び、自動的に選択状態を更新する。

ActivityのonCreate()内で、

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

    // ・・・

    val navController = findNavController(R.id.nav_host_fragment)
    findViewById<BottomNavigationView>(R.id.bottom_nav)
        .setupWithNavController(navController)
}
```



今回記事は以上です。