Search code examples
androidratingbar

Make the RatingBar secondary color opaque


I'm trying to make the un-filled stars in the RatingBar an opaque color, but it seems like a tall task consisting of tint lists and PorterDuff Modes. Is there a rock solid way to make the un-filled stars of a RatingBar a truely opaque color?

val color = ContextCompat.getColor(context, android.R.color.white)
ratingBar.secondaryProgressTintList = ColorStateList.valueOf(white)
ratingBar.secondaryProgressTintMode = PorterDuff.Mode.OVERLAY //whats the sauce?

The un-filled color is still transparent, and the background of the view is half white!


Solution

  • The stars in a RatingBar are simply a LayerDrawable. The key to setting the color of unfilled stars is to get a handle on the index within the LayerDrawable that contains a description of the drawable for unfilled stars (index = 0). Once we have that drawable, we can color it with "Drawable#setTint()" for API 21+ or with "Drawable#setColorFilter()" for API <21.

    The following example sets the unfilled stars to an opaque green:

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            RatingBar ratingBar = findViewById(R.id.ratingBar);
            LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
            int unfilledColor = getResources().getColor(android.R.color.holo_green_dark);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                stars.getDrawable(0).setTint(unfilledColor);
            } else {
                stars.getDrawable(0).setColorFilter(unfilledColor, PorterDuff.Mode.SRC_ATOP);
            }
        }
    }
    

    enter image description here