⭐️

Jetpack Composeでドラッグ可能なRatingBarを作成する

2025/02/27に公開

はじめに

こんにちは、Kamachiです。Jetpack Composeを使用するにあたり、ドラッグ可能なRatingBarの実装が必要になったため調査しました。
しかし、その具体的な実装方法が明確にならなかったため、健忘録として本記事を書くことにしました。結論として、Sliderを活用することで、ドラッグ操作に対応したRatingBarを実現することができました。この実装方法を詳しく解説していきます。

star.gif

ドラッグが必要な理由は二つあります。一つは、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なため、仕様が変更される可能性があります。最新の情報を確認することをお勧めします。

助太刀について

助太刀では一緒に開発してくれるメンバを募集してます!
少しでもご興味を持っていただけたら下記よりお気軽にご連絡ください!

参考記事

https://developer.android.com/codelabs/basic-android-kotlin-training-compose-add-compose-to-a-view-based-app?hl=ja#0
https://developer.android.com/develop/ui/compose/components/slider
https://zenn.dev/u_dai/articles/11f87d40045aac

助太刀テックブログ

Discussion