Android Navigation を使った引数の渡し方

# はじめに
この記事は Goodpatch Advent Calendar 2019 13日目の記事です

今年を振り返り私自身Android開発に大きな目玉機能だなと思ったのは2019年4月に正式リリースされたNavigation機能だと思っています。
Navigation機能を簡単に説明するとGUI上でAndroidの画面表示機能の1つFragmentを管理しやすくなった機能です。

以前だと、Fragmentを管理するためにはコードを記述してそのなかで管理する必要がありました。
そのため画面管理するのに設計したり、テストしたりとコードを書く以外に時間をかける必要がありました。

しかし Navigationの登場のおかげでFragmentの管理がコードから視覚的にわかるGUIに変更されたため
急な画面変更が発生し、遷移の仕方が変わったとしてもカジュアルに変更することができるようになりました。

Navigationを使いブイブイ画面を作ることはらくらくできたのですが、Fragmentで引数を渡すところで私自身結構つまづいてしまったので
今回はそのNavigationの引数の渡し方について紹介させてください。

## 利用する時に必要になる plugin 一覧
まずNavigationを扱うためにGradleの設定で以下の記述が必要となってきます。

```groovy
apply plugin: "androidx.navigation.safeargs.kotlin"
dependencies {
	implementation "android.arch.navigation:navigation-fragment:1.0.0"
	implementation "android.arch.navigation:navigation-ui:1.0.0"
	implementation "android.arch.navigation:navigation-fragment-ktx:1.0.0"
	implementation "android.arch.navigation:navigation-ui-ktx:1.0.0"
}
```

app Gradle のほかに Project Gradleにも記述が必要があるので忘れずに記述しましょう！

```groovy
dependencies {
	classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
}
```

## Navigation内で扱いたいFragmentの追加の仕方
![スクリーンショット 2019-12-21 18.36.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67480/3ac970d4-31fd-acd0-3cfb-2049dc2ee64a.png)
この画面がNavigationを管理する画面で、今回はnavigation_hostという名前で作業しています。
管理したいFragmentの追加方法はxmlを記入でもできますし、GUIからだと+がついたアイコンから追加することができます。

## Fragmentに対し引数追加の仕方
### Navigationファイルで事前設定

1. 右側にあるメニューからArgument横にある+をクリックし、ダイアログを表示
![スクリーンショット 2019-12-21 19.05.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67480/f6774fc6-87c2-3425-4a83-b338197ab70d.png)

2. 追加したい引数を設定
![スクリーンショット 2019-12-21 19.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67480/cc1f9903-108a-5ee6-2830-67bf3cbd8023.png)
![スクリーンショット 2019-12-21 19.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67480/89496345-45f1-951b-dd81-3cbfe83391ea.png)
独自ClassはParcelableやSerializableを使うと渡せるようになります
![スクリーンショット 2019-12-21 19.05.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67480/4cc4540a-2b4a-7035-2678-14440c3de16b.png)

設定を行ったあと、XMLでファイルを覗いてみるとfragmentの中にargumentの内容が追加されます。

## actionで引数を渡すやりかた

```kotlin
binding.button.setOnClickListener {
     val action = FirstFragmentDirections.actionFirstFragmentToSecondFragment("hoge")
     findNavController().navigate(action)
}
```


Navigationの引数追加を終えてClean Projectを行うと`action~`メソッドが使えるようになり、
引数を渡せるようになります。



## bundleを使って引数を渡すやりかた

```kotlin

binding.button.setOnClickListener {
     findNavController().navigate(R.id.thirdFragment, Bundle().apply {
          putString("hogehoge", "hogehoge")
     }
}
```
ポイントはNavigationファイルで設定した argumentの指定の中にある `android:name` と一致させる必要があります。


## 感想
Fragmentの管理がコードからGUIに変わったので、前だったら紙等で整理してから書くようにしていたのですが
Navigationを使うと簡単に付け替えができるので変更することができるのが利点だと感じました。

開発は絶対手戻りしないと心がけても何かしらの影響で修正が余儀なくされてしまうため、
Fragmentの管理がめんどくさくなりActivityだけで完結させてしまう欲がたびたびあったのですが
壊しても簡単に組み立て直すことができるのでアプリの品質を向上できそうです。

ただNavigationを使い、BuildをするとまだそんなにBiuldエラーの内容が親切じゃないため
どこでエラーになったのか調査するのに時間がかかってしまう時があります。
そのためNavigationを扱う時にはこまめにBiuldをすると、どこでエラーになったのか分かりやすくなるため
こまめにBuildをしていたほうがいいと思いました。

Buildエラーの中には Clean up Project で エラーが解消するときがあるので
エラーが発生したとしても焦らず、寛大な気持ちで対応する心が大事です。

# おわりに

今回紹介した内容はgithubで共有してみました
興味があるかたは触ってもらえるとうれしいです
https://github.com/hayato-k/navigation-argument