Simon Simon - 3 months ago 52
Android Question

Android RatingBar: Cannot fill in a partial ratingBar if I customise it's color

I have set the ratingBar color to a different color to Android's default blue and gray - I have made my stars with a black background and pink if they are selected.

This is my code for my mainactivity:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingbar);
LayerDrawable layerDrawable2 = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0)),
ContextCompat.getColor(getApplicationContext(), android.R.color.background_dark));
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1)),
ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); // Partial star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2)),
ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));
ratingBar.setIsIndicator(false);
ratingBar.setRating(3.6f);
ratingBar.setStepSize(0.1f);
ratingBar.invalidate();
ratingBar.setIsIndicator(true);
}
}


You can see that if I put in the rating as 3.6, it selects up to 4.

enter image description here

However, if I comment out my own customised colors, the ratingBar sets itself correctly to display only a part of the 4th star as filled in as the value passed to it was 3.6:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingbar);
/* LayerDrawable layerDrawable2 = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0)),
ContextCompat.getColor(getApplicationContext(), android.R.color.background_dark));
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1)),
ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); // Partial star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2)),
ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));*/
ratingBar.setIsIndicator(false);
ratingBar.setRating(3.6f);
ratingBar.setStepSize(0.1f);
ratingBar.invalidate();
ratingBar.setIsIndicator(true);
}
}


enter image description here

Why is it that if I create my own custom colors, the ratingBar doesn't fill itself properly?

I have created a small repo and you can download it and test it here: https://github.com/Winghin2517/RatingBarTest2

EDIT:

FlyingPumba's library shows some promise on what I want to achieve but I would need a style where the stars background is white when it appears on the screen and it will be filled by a solid color when users press the star. In my case, I want it to be filled with a green color.

The below is what I was able to achieve but it is not quite there yet. I changed the scrollview background in which the stars sit to pink so that you can see that instead of a white background for the stars, the pink from the scrollview background shines through. For my use case , I want white stars to sit in front of an imageview and I do not want the image in the imageview to shine through the stars.

Also I do not need white stroke for the stars at all as I want to keep the styling of the stars simple.

<com.iarcuschin.simpleratingbar.SimpleRatingBar
android:id="@+id/ratingBar3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:srb_rating="3.6"
app:srb_fillColor="@color/material_greenA700"
app:srb_borderColor="@color/material_white"
app:srb_starBorderWidth="0"
app:srb_pressedFillColor="@color/material_greenA700"
app:srb_starSize="30dp"
/>


enter image description here

Answer

You are on the right track with what you are trying. The only thing you have done wrong is to assign the wrong colour to the 2nd drawable.

Think of the 2nd drawable as the background of the star, not the foreground. So the partial stars need the background colour, not the colour of the stars i.e. in your example, black, not pink.

Below is the corrected code, which works as described. I have reformatted it slightly to highlight the change required.

    RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingbar);
    LayerDrawable layerDrawable2 = (LayerDrawable) ratingBar.getProgressDrawable();

    // No star
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0)),
            ContextCompat.getColor(getApplicationContext(),
                    android.R.color.background_dark));

    // Partial star 
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1)),
            ContextCompat.getColor(getApplicationContext(),
                    // use background_dark instead of colorAccent
                    // R.color.colorAccent));
                    android.R.color.background_dark));

    // Custom star
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2)),
            ContextCompat.getColor(getApplicationContext(),
                    R.color.colorAccent));