Jetpack ComposeでTabにバッジをつける方法

今回はJetpack ComposeでTabにバッジをつける方法です

未読のお知らせ等があるときにタブにバッジを表示させたいことがあると思います。

実装方法です。

# androidx.compose.materialの導入


[androidx.compose.material](https://developer.android.com/jetpack/androidx/releases/compose-material?hl=ja)
を導入します。

```
dependencies {
  implementation "androidx.compose.material:material:${latest.version}"
}
```

androidx.compose.materialを導入すると``BadgedBox``や``Badge``を使用することができ、こちらを使用してバッジを実装していきます。

# バッジの実装

表示するタブのアイコンと、表示するテキストのデータを作っておきます。
``` Screen.kt
val tabData = listOf(
    "ホーム" to Icons.Filled.Home,
    "カート" to Icons.Filled.ShoppingCart,
    "お知らせ" to Icons.Filled.Notifications,
)
```

タブ部分の実装の箇所だけ切り抜いてます。
``` Screen.kt
TabRow(selectedTabIndex = tabIndex,
    modifier = Modifier.fillMaxWidth(),
    backgroundColor = Color.White) {
    tabData.forEachIndexed { index, pair ->
        Tab(selected = tabIndex == index, onClick = {
            coroutineScope.launch {
                pagerState.animateScrollToPage(index)
            }
        }, text = {
            Text(text = pair.first)
        }, icon = {
            BadgedBox(badge = { Badge { Text("1") } }) {
                Icon(
                    pair.second,
                    contentDescription = pair.first
                )
            }
        })
    }
}
```

こちらで実行するとこのようになるはずです。

![スクリーンショット 2022-09-11 15.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/e93a4136-187a-34ad-74c4-0e618b0c3e23.png)

# アイコンを使用しない場合

アイコンを使用しない場合は、このように実装するとできます。
``` Screen.kt
Tab(selected = tabIndex == index, onClick = {
    coroutineScope.launch {
        pagerState.animateScrollToPage(index)
    }
}, icon = {
    BadgedBox(badge = { Badge { Text("1") } }) {
        Text(text = pair.first)
    }
})
```

![スクリーンショット 2022-09-11 15.20.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/9dc1150b-cc02-9e91-30a2-f071979aa4b0.png)

# バッジの中の文字数が増えた時

ここまで見るとお分かりだと思いますが、``Badge { Text("1") } ``でバッジの中の数字が表示されています。

ではバッジの中の数字が増えると、どうなのででしょうか？

![スクリーンショット 2022-09-11 15.22.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/75af1af4-810c-8bed-c62b-f45ffe5245c9.png)
このように横幅が広がってくれます。

# テキストを無くしたい場合

```Screen.kt
Tab(selected = tabIndex == index, onClick = {
    coroutineScope.launch {
        pagerState.animateScrollToPage(index)
    }
}, icon = {
    BadgedBox(badge = { Badge {} }) {
        Text(text = pair.first)
    }
})
```


テキストを無くすと、丸いバッジのみになります。

![スクリーンショット 2022-09-11 15.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/c3c4bbce-5220-11a6-e5a2-14552f511c66.png)

# バッジのサイズの変更

バッジのサイズが大きいなぁー、と思ってませんか？サイズも調整できます。
```Screen.kt
Tab(selected = tabIndex == index, onClick = {
    coroutineScope.launch {
        pagerState.animateScrollToPage(index)
    }
}, icon = {
    BadgedBox(badge = { Badge(modifier = Modifier.width(6.dp).height(6.dp)) {}
        Text(text = pair.first)
    }
})
```

![スクリーンショット 2022-09-11 15.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/95c95565-2292-ebba-71e6-a76dab43d258.png)

ちょうどいい大きさになりましたね!

# バッジの位置調整

バッジの位置も調整できます！
今回はわかりやすいように動かしてみました。
``offset``を使用します。
```Screen.kt
Tab(selected = tabIndex == index, onClick = {
    coroutineScope.launch {
        pagerState.animateScrollToPage(index)
    }
}, icon = {
    BadgedBox(badge = { Badge(modifier = Modifier.width(6.dp).height(6.dp).offset(x = 8.dp, y = (-8).dp)) {} }) {
        Text(text = pair.first)
    }
})
```

![スクリーンショット 2022-09-11 15.35.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/7e10c435-3caa-a842-6ff4-c0b4d9702747.png)

このようになります。


以上、Jetpack ComposeでTabにバッジをつける方法でした！