⭐️
Jetpack Composeでドラッグ可能なRatingBarを作成する
はじめに
こんにちは、Kamachiです。Jetpack Composeを使用するにあたり、ドラッグ可能なRatingBarの実装が必要になったため調査しました。
しかし、その具体的な実装方法が明確にならなかったため、健忘録として本記事を書くことにしました。結論として、Sliderを活用することで、ドラッグ操作に対応したRatingBarを実現することができました。この実装方法を詳しく解説していきます。
ドラッグが必要な理由は二つあります。一つは、AndroidViewと同じ使用感を提供するためです。二つ目は、一度設定した値をEmptyに戻すためです。
Emptyに戻す方法として、すでに評価した値と同じ値をタップすることでEmptyに戻す方法もありますが、誤タップのリスクがあります。ドラッグでEmptyに戻すことで、ユーザビリティの向上を図りました。
ドラッグが不要な場合は、公式のcodelabsに記載されている方法で実装可能です。
RatingBarの実装方法
1. Starの作成
まず、"星"と"空の星"を切り替え可能なIconを作成します。
@Composable
private fun Star(
filled: Boolean,
) {
Icon(
painter = painterResource(id = if (filled) R.drawable.ic_star_fill else R.drawable.ic_star_empty),
contentDescription = null,
tint = Color(0xFFFFDC33),
modifier = Modifier.size(42.dp),
)
}
2. Trackの作成
次に、RatingBarのTrackを作成します。Trackでは、trackSizeの数だけStarを並べます
引数 | 説明 |
---|---|
trackSize | RatingBarの最大値 |
rating | RatingBarの値 |
@Composable
private fun Track(
trackSize: Int,
rating: Float,
) {
Row {
repeat(trackSize) { i ->
Star(
filled = i < rating,
)
}
}
}
3. RatingBarの作成
最後に、Sliderのtrackに上記のTrackを使用します。
引数 | 説明 |
---|---|
modifier | Modifier |
trackSize | RatingBarの最大値 |
value | RatingBarの値 |
onValueChange | RatingBarの値が変更された時の処理 |
onRatingChanged | RatingBarの値が変更された時の処理 |
valueRange | RatingBarの値の範囲 |
@Composable
fun RatingBar(
modifier: Modifier = Modifier,
trackSize: Int = 5,
value: Float,
onValueChange: (Float) -> Unit,
onRatingChanged: () -> Unit = {},
valueRange: ClosedFloatingPointRange<Float> = 0f..trackSize.toFloat(),
) {
Slider(
modifier = modifier,
value = value,
onValueChange = { if (it < trackSize.toFloat()) onValueChange(it) },
onValueChangeFinished = onRatingChanged,
valueRange = valueRange,
thumb = {},
track = {
Track(
trackSize = trackSize,
rating = value,
)
},
)
}
まとめ
Sliderを使用することで、タップとドラッグの両方に対応したRatingBarを作成することができました。ただし、この記事作成時点でSliderはExperimentalなため、仕様が変更される可能性があります。最新の情報を確認することをお勧めします。
助太刀について
助太刀では一緒に開発してくれるメンバを募集してます!
少しでもご興味を持っていただけたら下記よりお気軽にご連絡ください!
参考記事
Discussion