KotlinでBottomNavigationにバッジをつける

BottomNavigationViewでバッジをつけるのにあれこれ調べたので記事書きます。
Material Components Androidのバージョン1.1.0-alpha06からバッジをつけれる機能が追加されたらしいです。

##フッターの準備

Android Studioを使って開発します。
最初にプロジェクトを作成する時にBottom Navigation Activityを選択しましょう。
![スクリーンショット 2019-11-11 15.08.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439548/9040dc92-3f49-8434-c738-173454a7cdbb.png)

これだけでもうフッター付きのアプリが作成されているはずです。
プロジェクトが立ち上がったらアプリを起動してみましょう。

```kotlin:MainActivity.kt
:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)

        navView.setupWithNavController(navController)
    }
}
```
<img width="313" alt="スクリーンショット 2019-11-11 15.14.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439548/7fc6ab84-3d41-39a2-0cc9-484d3b760f6f.png">

##下準備
フッターのアイコンにバッジを表示させるために少しだけ事前準備が必要です。
まずは`build.gradle(Module: app)` で最新のMaterial Components Androidを追加します。
最新のバージョンは
https://github.com/material-components/material-components-android/releases
ここで知ることができます。
今回は1.1.0-beta02を使います。

```
implementation 'com.google.android.material:material:1.0.0'
```
と書かれている部分を

```
implementation 'com.google.android.material:material:1.1.0-beta02'
```
に書き換えましょう。
これでMaterial Components Androidが最新バージョンになりました。

次にTheme.MaterialComponentsを継承するように`/res/values/styles.xml` を書き換えます。
(これに気付くのに少し時間かかった…)

```xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
```

と書いてある部分を

```xml
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
```
に書き換えます。
これでTheme.MaterialComponentsを継承するようになりました。

##バッジの実装
それではフッターにバッジを表示させてみましょう。

 `getOrCreateBadge(itemId)` を使うことでアイコンにバッジを表示させることができます。
たとえば、上で作成したフッターの`Notifications`のアイコンに`10`を表示させたい時は、

```kotlin
navView.menu.getItem(2).itemId.let {
  navView.getOrCreateBadge(it).apply {
    number = 10
  }
}
```
という風に書けば表示されます。

全体的なコードはこんなかんじ。

```kotlin:MainActivity.kt
:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        navView.menu.getItem(2).itemId.let {
            navView.getOrCreateBadge(it).apply {
                number = 10
            }
        }

        val navController = findNavController(R.id.nav_host_fragment)

        navView.setupWithNavController(navController)
    }
}

```
<img width="311" alt="スクリーンショット 2019-11-11 15.33.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439548/7db33bb7-ddc4-1de3-05d1-bed803549009.png">

これでバッジが実装できました。
しかしこのままだとnumberが0のときもバッジが表示されてしまいます。
<img width="312" alt="スクリーンショット 2019-11-11 15.34.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439548/aa4dd891-a83f-231c-2bb4-14082c0295db.png">

```kotlin
inVisible = false
```
を付け加えることでバッジの表示非表示を変更できます。

```kotlin
navView.menu.getItem(2).itemId.let {
    navView.getOrCreateBadge(it).apply {
        number = 0

        if (number == 0) {
            isVisible = false
        }
    }
}
```
また、バッジの背景色は`backgroundColor`で変更が可能です。

```kotlin
navView.menu.getItem(2).itemId.let {
    navView.getOrCreateBadge(it).apply {
        backgroundColor = Color.BLUE
        number = 10
    }
}
```
<img width="313" alt="スクリーンショット 2019-11-11 15.44.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439548/c8866105-c76f-54b9-07b1-8b815b7e273d.png">

##参考
[BottomNavigationViewにバッジを表示する](https://qiita.com/pongi/items/85e237afa96aa83bc198)
[【Android】MaterialComponentsのComponent別Badge付け方まとめ](https://qiita.com/youmeee/items/75795f5314d852d74485)
[Material Components for Android](https://github.com/material-components/material-components-android/)