Docs / Components / 04

ComposeRatingBar

A row of stars, hearts, circles, or any Shape or Painter, for showing and picking a rating. Tap an item to rate, or drag across the bar and the rating follows your finger.

  • Value + callback
  • Tap & drag
  • Any Shape or Painter
  • Animated

Preview

How it works

  • Stateless. You pass rating and update it in onRatingChange, which runs while the user taps or drags. onRatingChangeFinished runs when the finger lifts, which is the place to save.
  • Read-only is onRatingChange = null. The bar then just shows the value, and fractional ratings such as 3.7f draw a partly filled item.
  • stepSize rounds the input. 1f for whole items, 0.5f for halves, 0f for any value. minRating stops the user going below a floor and allowClear decides whether tapping the current rating resets it.
  • Any item. Use the built-in StarShape, SharpStarShape and HeartShape, build a star with starShape(points, innerRadiusRatio, roundness), pass any Compose Shape, or a Painter that gets tinted with the bar's colors.
  • Animation runs in the draw phase. Items fill one after another, the tapped one pops with a halo and the one under your finger lifts, without recomposing the bar. Tune it with RatingBarAnimation(...) or turn it off with .None.

Setup

Add the library once (see Getting started), then import from com.nameisjayant.components.ratingbar:

Imports
import com.nameisjayant.components.ratingbar.*

Quick start

ComposeRatingBar.kt
var rating by rememberSaveable { mutableFloatStateOf(3f) }

ComposeRatingBar(
    rating = rating,
    onRatingChange = { rating = it },
    onRatingChangeFinished = { viewModel.save(rating) },   // when the finger lifts
)

Steps, read-only and limits

ComposeRatingBar.kt
ComposeRatingBar(rating, { rating = it }, stepSize = 0.5f)     // halves (1f = whole, 0f = any value)

ComposeRatingBar(rating = 3.7f, onRatingChange = null)         // read-only; fractions draw partly filled

ComposeRatingBar(
    rating = rating,
    onRatingChange = { rating = it },
    maxRating = 10,
    minRating = 1f,                                            // at least one star
    allowClear = false,                                        // tapping the current rating won't reset it
)

Shapes and colors

ComposeRatingBar.kt
// Gold stars
ComposeRatingBar(rating, { rating = it }, colors = ComposeRatingBarDefaults.accentColors(ComposeRatingBarDefaults.Gold))

// Hearts
ComposeRatingBar(rating, { rating = it }, shape = ComposeRatingBarDefaults.HeartShape,
    colors = ComposeRatingBarDefaults.accentColors(Color(0xFFE5484D)))

// Outline-only empty stars
ComposeRatingBar(rating, { rating = it }, shape = ComposeRatingBarDefaults.SharpStarShape,
    borderWidth = ComposeRatingBarDefaults.OutlineWidth, colors = ComposeRatingBarDefaults.outlinedColors())

// Any star, or any Compose shape
ComposeRatingBar(rating, { rating = it }, shape = ComposeRatingBarDefaults.starShape(points = 6, innerRadiusRatio = 0.5f, roundness = 0.3f))
ComposeRatingBar(rating, { rating = it }, shape = CircleShape, itemSize = 20.dp, itemSpacing = 4.dp)

// An icon, tinted with the bar's colors
ComposeRatingBar(rating, { rating = it }, painter = painterResource(R.drawable.ic_thumb_up))

Animation

When the rating grows, items fill one after another with a soft bounce, the tapped item pops and sends out a halo, and the item under your finger lifts while you drag.

ComposeRatingBar.kt
ComposeRatingBar(
    rating, { rating = it },
    animation = RatingBarAnimation(staggerMillis = 80, popScale = 1.4f, showHalo = false), // or RatingBarAnimation.None
)

All parameters

ParameterDefaultDescription
ratingCurrent rating, 0..maxRating
onRatingChangeNew rating while tapping or dragging; null makes the bar read-only
maxRating5Number of items
stepSize1f1f whole, 0.5f halves, 0f any value
minRating0fLowest rating the user can pick
enabledtrueIgnore input and use the disabled colors when false
allowCleartrueTapping the current rating resets it to minRating
itemSize / itemSpacing32.dp / 6.dpItem size and gap
shapeStarShapeStarShape, SharpStarShape, HeartShape, starShape(points, innerRadiusRatio, roundness) or any Shape
painternullDraw a tinted Painter instead of shape
borderWidth0.dpStroke around each item; use OutlineWidth with outlinedColors()
colorsComposeRatingBarDefaults.colors()activeColor, inactiveColor, activeBorderColor, inactiveBorderColor, disabledActiveColor, disabledInactiveColor, haloColor
animationRatingBarAnimation.DefaultRatingBarAnimation(staggerMillis, waveScale, popScale, dragScale, showHalo) or .None
hapticFeedbackEnabledtrueTick as the rating changes under the finger
onRatingChangeFinishednullCalled when a tap or drag ends

TalkBack users can adjust the rating with the standard slider actions. Right-to-left layouts fill from the right. Animations run in the draw phase, so the bar doesn't recompose while it moves.

API

The public signatures, straight from the library sources:

com.nameisjayant.components.ratingbar
@Composable
public fun ComposeRatingBar(
    rating: Float,
    onRatingChange: ((Float) -> Unit)?,
    modifier: Modifier = Modifier,
    maxRating: Int = 5,
    stepSize: Float = 1f,
    minRating: Float = 0f,
    enabled: Boolean = true,
    allowClear: Boolean = true,
    itemSize: Dp = ComposeRatingBarDefaults.ItemSize,
    itemSpacing: Dp = ComposeRatingBarDefaults.ItemSpacing,
    shape: Shape = ComposeRatingBarDefaults.StarShape,
    painter: Painter? = null,
    borderWidth: Dp = 0.dp,
    colors: ComposeRatingBarColors = ComposeRatingBarDefaults.colors(),
    animation: RatingBarAnimation = RatingBarAnimation.Default,
    hapticFeedbackEnabled: Boolean = true,
    onRatingChangeFinished: (() -> Unit)? = null,
)