Wed. Jan 15th, 2025

Jetpack Compose does not have a direct equivalent to the traditional RatingBar in the Android View system. However, you can easily create a custom rating bar using composables like Row, Icon, or Image to represent the stars and manage the state to track the rating value.


Example: Simple Rating Bar

@Composable
fun RatingBar(
    rating: Int,
    onRatingChanged: (Int) -> Unit,
    maxRating: Int = 5
) {
    Row(horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
        for (i in 1..maxRating) {
            Icon(
                imageVector = if (i <= rating) Icons.Default.Star else Icons.Default.StarBorder,
                contentDescription = "Rating $i",
                modifier = Modifier
                    .size(32.dp)
                    .clickable { onRatingChanged(i) },
                tint = Color.Yellow
            )
        }
    }
}

How to Use It:

@Composable
fun RatingBarExample() {
    var rating by remember { mutableStateOf(3) }

    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxSize()
    ) {
        Text(text = "Rating: $rating", style = MaterialTheme.typography.h6)
        Spacer(modifier = Modifier.height(16.dp))
        RatingBar(rating = rating, onRatingChanged = { newRating -> rating = newRating })
    }
}

Explanation:

  1. State Management:
  • rating keeps track of the current rating selected by the user.
  • onRatingChanged updates the rating when a star is clicked.
  1. Customizable:
  • maxRating allows you to set the maximum number of stars.
  • The tint parameter sets the star color (Color.Yellow in this case).
  1. Icons:
  • Icons.Default.Star: Filled star for selected ratings.
  • Icons.Default.StarBorder: Outline star for unselected ratings.

Advanced Rating Bar with Half Stars

For half-star ratings, you can use Image or custom draw logic.

@Composable
fun AdvancedRatingBar(
    rating: Float,
    onRatingChanged: (Float) -> Unit,
    maxRating: Int = 5
) {
    Row(horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
        for (i in 1..maxRating) {
            val isHalfFilled = rating > i - 1 && rating < i
            Icon(
                imageVector = when {
                    i <= rating -> Icons.Default.Star
                    isHalfFilled -> Icons.Default.StarHalf
                    else -> Icons.Default.StarBorder
                },
                contentDescription = "Rating $i",
                modifier = Modifier
                    .size(32.dp)
                    .clickable { onRatingChanged(i.toFloat()) },
                tint = Color.Yellow
            )
        }
    }
}

How to Use It:

@Composable
fun AdvancedRatingBarExample() {
    var rating by remember { mutableStateOf(3.5f) }

    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxSize()
    ) {
        Text(text = "Rating: ${"%.1f".format(rating)}", style = MaterialTheme.typography.h6)
        Spacer(modifier = Modifier.height(16.dp))
        AdvancedRatingBar(rating = rating, onRatingChanged = { newRating -> rating = newRating })
    }
}

Customization:

  • Icon Size: Modify the Modifier.size() parameter for smaller or larger stars.
  • Colors: Change the tint to any color.
  • Shapes: Replace Icons.Default with custom drawable resources or SVGs.

Feel free to ask if you want further customizations or additional features like animations for the stars!

By Rajashekar

I’m (Rajashekar) a core Android developer with complimenting skills as a web developer from India. I cherish taking up complex problems and turning them into beautiful interfaces. My love for decrypting the logic and structure of coding keeps me pushing towards writing elegant and proficient code, whether it is Android, PHP, Flutter or any other platforms. You would find me involved in cuisines, reading, travelling during my leisure hours.

Leave a Reply

Your email address will not be published. Required fields are marked *