10

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

Simon
  • 19,658
  • 27
  • 149
  • 217
  • I added some features to the library that will allow you accomplish what you wanted (look at the example layout I added to the answer). – FlyingPumba Aug 14 '16 at 04:47

4 Answers4

4

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));

Another way to do this, and possibly better in many cases, is to use proper styling on the RatingBar.

This requires setting a custom style for the rating bar, then defining the layer drawables used by that style to point to your own images or colours.

I am not going to go into further detail, because the actual xml code is shown in Anantham's answer.

Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
1

in Activity.java:

oncreate :

       RatingBar   setRatingBar = (RatingBar) findViewById(R.id.setRating);
       float rating = Float.parseFloat(listString);
      // onRatingChanged(setRatingBar, 0.0f, true);

        public void onRatingChanged(RatingBar rateBar, float rating, boolean fromUser) {
    try {
        DecimalFormat decimalFormat = new DecimalFormat("#.#");
        curRate = Float.valueOf(decimalFormat.format((curRate * count + rating)/ ++count));
        float userRatePoint = curRate/**20*/;

        setRatingBar.setRating(userRatePoint);
        countText = (TextView) findViewById(R.id.countText);
        countText.setText(userRatePoint + " Ratings");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

then try this for smallstar rating bar:

    <RatingBar
     android:id="@+id/setRating"
     style="?android:attr/ratingBarStyleSmall"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_marginLeft="10dp"
     android:layout_marginTop="3dp"
     android:isIndicator="true"
     android:numStars="5"
     android:stepSize="0.1" />
       //if you want to style please use "foodRatingBar"
       //for custom star image use  "ratingstar"

style.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="foodRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/ratingstar</item>
    <item name="android:minHeight">22dip</item>
    <item name="android:maxHeight">22dip</item>
</style>

values v11/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="foodRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/ratingstar</item>
    <item name="android:minHeight">22dip</item>
    <item name="android:maxHeight">22dip</item>
</style>

values v14/styles.xml

 <resources>
   <style name="foodRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/ratingstar</item>
    <item name="android:minHeight">22dip</item>
    <item name="android:maxHeight">22dip</item>
</style>
<!--
    Base application theme for API 14+. This theme completely replaces
    AppBaseTheme from BOTH res/values/styles.xml and
    res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <!-- API 14 theme customizations can go here. -->
</style>
</resources>

ratingstar.xml - this is where the custom progress images are defined

<?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@android:id/background"
            android:drawable="@drawable/ratingstar_default" />
        <item android:id="@android:id/secondaryProgress"
            android:drawable="@drawable/ratingstar_default" />
        <item android:id="@android:id/progress"
            android:drawable="@drawable/ratingstar_selected" />
    </layer-list>
</resources>
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
MurugananthamS
  • 2,395
  • 4
  • 20
  • 49
  • This doesn't look like it is for an indicator rating bar? – Simon Aug 13 '16 at 07:24
  • addListenerOnRatingBar() inside this method i implemented "setOnRatingBarChangeListener" i also implement the rating bar for my app – MurugananthamS Aug 13 '16 at 07:25
  • Can u please show me what is ur @style/foodratingbar? – Simon Aug 13 '16 at 07:28
  • Please test your answer with my repo before posting - i tried your solution now and it is not the indicator style for the ratingbar. I'm looking to change the indicator style which makes the small stars, not the normal style with the big stars. – Simon Aug 13 '16 at 08:28
  • i just post for small star check this@Simon – MurugananthamS Aug 13 '16 at 09:34
  • This answer is very difficult to understand because of the way it is laid out. But the actual styles you make seem to be done "the proper way" instead of the original question uses. Please clean it up and explain what you are doing - it should be getting more votes. – Richard Le Mesurier Aug 20 '16 at 08:42
  • 1
    i just edit my post ,thanks for your feedback @RichardLeMesurier – MurugananthamS Aug 20 '16 at 10:26
  • 1
    I hope you don't mind my edit - I'm trying to make it clear what you are showing. +1 cos this is the right way to do it, although in reality so many of us just use the hack I fixed with. – Richard Le Mesurier Aug 20 '16 at 10:35
  • thanks for edit my answer in proper way@RichardLeMesurier – MurugananthamS Aug 20 '16 at 10:38
-1

You just need to update DrawableCompat.wrap(..) drawable with .mutate(). you code is look as below:

DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0).mutate()),
            ContextCompat.getColor(getApplicationContext(), android.R.color.background_dark));
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1).mutate()),
            ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); // Partial star
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2).mutate()),
            ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));

If the color is changed dynammicaly the drawable must be mutable

See Question : Android: Tint using DrawableCompat

and answer : https://stackoverflow.com/a/30928051/2949612

You can See Drawable mutations blog by Romain Guy and also see mutate() method android developer doc.

I hope its helps you.

Community
  • 1
  • 1
pRaNaY
  • 24,642
  • 24
  • 96
  • 146
  • Please test this with my repo before posting the answer - i just tried my repo with mutate() and it doesn't work. – Simon Aug 06 '16 at 17:13
  • 1
    repo is updated with mutate so you can just download it and test it for yourself. – Simon Aug 06 '16 at 17:13
-1

Using the stock RatingBar can be very painful, you should try this library: SimpleRatingBar.

(I'm a bit biased, as I'm the creator)

It features:

  • Fully working android:layout_width: it can be set to wrap_content, match_parent or abritary dp.
  • Arbitrary number of stars.
  • Arbitrary step size.
  • Size of stars can be controlled exactly or by setting a maximum size.
  • Customizable colors in normal state (border, fill and background of stars).
  • Customizable colors in pressed state (border, fill and background of stars).
  • Customizable size separation between stars.
  • Customizable border width of stars.
  • Customizable stars corner radius.
  • Allows to set OnRatingBarChangeListener
  • Stars fill can be set to start from left to right or from right to left (RTL language support).
  • AnimationBuilder integrated in the view to set rating programatically with animation.

Here is a preview of it.

You can find it either in jcenter or in Maven Central. So in your build.gradle file just add to your dependencies:

compile 'com.iarcuschin:simpleratingbar:0.1.+'

EDIT: I recently added the possibility of changing the background color of stars (empty color) and disabling border. To achieve what you wanted you can add to your layout:

<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_starBackgroundColor="@color/white"
    app:srb_fillColor="@color/material_greenA700"
    app:srb_borderColor="@color/material_white"
    app:srb_pressedFillColor="@color/material_greenA700"
    app:srb_starSize="30dp"
    app:srb_drawBorderEnabled="false"
    />

I hope it's useful.

FlyingPumba
  • 1,015
  • 2
  • 15
  • 37
  • very impressive library and you did this all with the view class within extending the ratingbar class from android. I do have questions about your library, i will post it in my question and you can answer it there. – Simon Aug 13 '16 at 09:05