Android RatingBar change star colors

AndroidRating

Android Problem Overview


How can I change the star colors and size of the stars?

Android Solutions


Solution 1 - Android

It's a little complicated at the mentioned blog, I've used a similar but simplier way. You do need 3 star images (red_star_full.png, red_star_half.png and red_star_empty.png) and one xml, that's all.

Put these 3 images at res/drawable.

Put there the following ratingbar_red.xml:

<?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/red_star_empty" />
    <item android:id="@android:id/secondaryProgress" android:drawable="@drawable/red_star_half" />
    <item android:id="@android:id/progress" android:drawable="@drawable/red_star_full" />
</layer-list>

and, finally, tell your ratingbar definition to use this, i.e.

<RatingBar android:progressDrawable="@drawable/ratingbar_red"/>

That's it.

Solution 2 - Android

Try this, if you only want to change color:

RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);

Solution 3 - Android

The easiest way that worked for me...if you are extending AppCompat Activity

In your build.gradle add latest appcompat library.

dependencies {  
    compile 'com.android.support:appcompat-v7:X.X.X' // where X.X.X version
}

Make your activity extend android.support.v7.app.AppCompatActivity

public class MainActivity extends AppCompatActivity {  
    ...
}

Declare custom style in your styles.xml file.

<style name="RatingBar" parent="Theme.AppCompat">  
    <item name="colorControlNormal">@color/indigo</item>
    <item name="colorControlActivated">@color/pink</item>
</style>  

Apply this style to your RatingBar via android:theme attribute.

<RatingBar  
    android:theme="@style/RatingBar"
    android:rating="3"
    android:stepSize="0.5"
    android:numStars="5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

Solution 4 - Android

From the API 21 on it's very easy to change the color of the stars with this three lines of code:

android:progressTint="@android:color/holo_red_dark"
android:progressBackgroundTint="@android:color/holo_red_dark"
android:secondaryProgressTint="@android:color/holo_red_dark" 

Doing it like this, you'll change:

  • the filled stars color (progressTint)
  • the unfilled stars color (progressBackgroundTint)
  • and the border color (secondaryProgressTint) of the stars

Solution 5 - Android

2015 Update

Now you can use DrawableCompat to tint all kind of drawables. For example:

Drawable progress = ratingBar.getProgressDrawable();
DrawableCompat.setTint(progress, Color.WHITE);

This is backwards compatible up to API 4

Solution 6 - Android

If you want to change color for all stars states you my use:

LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(getResources().getColor(R.color.starFullySelected), PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(1).setColorFilter(getResources().getColor(R.color.starPartiallySelected), PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(0).setColorFilter(getResources().getColor(R.color.starNotSelected), PorterDuff.Mode.SRC_ATOP);

Solution 7 - Android

Step #1: Create your own style, by cloning one of the existing styles (from $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml), putting it in your own project's styles.xml, and referencing it when you add the widget to a layout.

Step #2: Create your own LayerDrawable XML resources for the RatingBar, pointing to appropriate images to use for the bar. The original styles will point you to the existing resources that you can compare with. Then, adjust your style to use your own LayerDrawable resources, rather than built-in ones.

Solution 8 - Android

The solutions that Alex and CommonsWares have posted are correct. One thing that the Android never talks about though is proper pixel sizes for different densities. Here are the required dimensions for each density based on halo light.

Small Star

mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px

Medium Star

mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px

Large Star

mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px

Solution 9 - Android

So I have been struggling with this issue for two hours and I have come up with a working solution for all API versions, where half stars ratings are also shown.

private void setRatingStarColor(Drawable drawable, @ColorInt int color)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        DrawableCompat.setTint(drawable, color);
    }
    else
    {
        drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }
}

You call the method with this order of drawables:

    LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
    // Filled stars
    setRatingStarColor(stars.getDrawable(2), ContextCompat.getColor(getContext(), R.color.foreground));
    // Half filled stars
    setRatingStarColor(stars.getDrawable(1), ContextCompat.getColor(getContext(), R.color.background));
    // Empty stars
    setRatingStarColor(stars.getDrawable(0), ContextCompat.getColor(getContext(), R.color.background));

NOTE: Also you must specify attributes "max" and "numStars" in XML, otherwise half stars aren't shown.

Solution 10 - Android

Now you can use DrawableCompat from AppCompat v22.1.0 onwards to dynamically tint all kind of drawables, useful when you're supporting multiple themes with a single set of drawables. For example:

LayerDrawable layerDrawable = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(0)), Color.RED);   // Empty star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(1)), Color.GREEN); // Partial star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(2)), Color.BLUE);  // Full star

This is backwards compatible down to API 4. Also see Chris Banes' blog post on Support Libraries v22.1.0

For the actual size and shape you will need to define a new style and layer-list drawables for the appropriate size, as others have already answered above.

Solution 11 - Android

For just changing the color of Rating bar from xml:-

android:progressTint="@color/your_color"
android:backgroundTint="@color/your_color"
android:secondaryProgressTint="@color/your_color"

Solution 12 - Android

Use android:theme attribute:

styles.xml

<style name="Theme.Rating" parent="Theme.AppCompat.Light">
    <item name="colorAccent">@color/rating</item>
</style>

layout.xml

<android.support.v7.widget.AppCompatRatingBar
    android:theme="@style/Theme.Rating"
    android:numStars="5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Solution 13 - Android

To change the color you just have to put set the parameter android:progressTint

 <RatingBar
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginTop="15dp"
        android:numStars="5"
        android:rating="1"
        android:progressTint="@android:/color/black"
        android:layout_gravity="center"
       />

For the size the style property.

Solution 14 - Android

The simpliest way:

android:progressTint="@color/color"

Solution 15 - Android

Withou adding a new style you can use the tint color within the RatingBar

             <RatingBar
                    android:id="@+id/ratingBar"
                    style="@android:style/Widget.Holo.RatingBar.Small"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:numStars="5"
                    android:rating="4.5"
                    android:stepSize="0.5"
                    android:progressTint="@color/colorPrimary"/>

Solution 16 - Android

Building @lgvalle's answer.

> 2015 Update

>Now you can use DrawableCompat to tint all kind of drawables. For example:

> Drawable progress = ratingBar.getProgressDrawable(); > DrawableCompat.setTint(progress, Color.WHITE); >This is backwards compatible up to API 4

LayerDrawable drawable = (LayerDrawable) getProgressDrawable();
Drawable progress = drawable.getDrawable(2);
DrawableCompat.setTint(progress, getResources().getColor(COLOR1));
progress = drawable.getDrawable(1);
DrawableCompat.setTintMode(progress, PorterDuff.Mode.DST_ATOP);
DrawableCompat.setTint(progress, getResources().getColor(COLOR1));
DrawableCompat.setTintMode(progress, PorterDuff.Mode.SRC_ATOP);
DrawableCompat.setTint(progress, getResources().getColor(COLOR2));
progress = drawable.getDrawable(0);
DrawableCompat.setTint(progress, getResources().getColor(COLOR2));

This will keep the fraction steps colors.

Solution 17 - Android

<!--For rating bar -->
    <style name="RatingBarfeed" parent="Theme.AppCompat">
        <item name="colorControlNormal">@color/colorPrimary</item>
        <item name="colorControlActivated">@color/colorPrimary</item>
    </style>

use your own color

Solution 18 - Android

Works for Android below and above version 21

After some research I've come up with this method to set the background tint, the gap tint (ex: half star) and the star tint color.

LayerDrawable layers = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(layers.getDrawable(0), 0x33000000); // The background tint
DrawableCompat.setTint(layers.getDrawable(1), 0x00000000); // The gap tint (Transparent in this case so the gap doesnt seem darker than the background)
DrawableCompat.setTint(layers.getDrawable(2), 0xffFED80A); // The star tint

Solution 19 - Android

Simple solution, use AppCompatRatingBar and its setProgressTintList method to achieve this, see this answer for reference.

Solution 20 - Android

I solve this issue this following:

LayerDrawable layerDrawable = (LayerDrawable) ratingBar.getProgressDrawable();

DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(0)),
                       Color.WHITE);  // Empty star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(1)),
                       Color.YELLOW); // Partial star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(2)),
                       Color.YELLOW);

Solution 21 - Android

RatingBar mRating=(RatingBar)findViewById(R.id.rating);
 LayerDrawable layerDrawable=(LayerDrawable)mRating.getProgressDrawable();
 layerDrawable.getDrawable(2).setColorFilter(Color.parseColor
 ("#32CD32"),    PorterDuff.Mode.SRC_ATOP);

for me its working....

Solution 22 - Android

I found a simple solution for changing the color of the star according to your theme.

Goto this site : http://android-holo-colors.com/

Choose your theme color and get your star images created.

Solution 23 - Android

Using the answers above, I created a quick static method that can easily be re-used. It only aims at tinting the progress color for the activated stars. The stars that are not activated remain grey.

    public static RatingBar tintRatingBar (RatingBar ratingBar, int progressColor)if (ratingBar.getProgressDrawable() instanceof LayerDrawable) {
        LayerDrawable progressDrawable = (LayerDrawable) ratingBar.getProgressDrawable();
        Drawable drawable = progressDrawable.getDrawable(2);
        Drawable compat = DrawableCompat.wrap(drawable);
        DrawableCompat.setTint(compat, progressColor);
        Drawable[] drawables = new Drawable[3];
        drawables[2] = compat;

        drawables[0] = progressDrawable.getDrawable(0);
        drawables[1] = progressDrawable.getDrawable(1);

        LayerDrawable layerDrawable = new LayerDrawable(drawables);

        ratingBar.setProgressDrawable(layerDrawable);

        return ratingBar;
    }
    else {
        Drawable progressDrawable =  ratingBar.getProgressDrawable();
        Drawable compat = DrawableCompat.wrap(progressDrawable);
        DrawableCompat.setTint(compat, progressColor);
        ratingBar.setProgressDrawable(compat);
        return ratingBar;
    }
}

Just pass your rating bar and a Color using getResources().getColor(R.color.my_rating_color)

As you can see, I use DrawableCompat so it's backward compatible.

EDIT : This method does not work on API21 (go figure why). You end up with a NullPointerException when calling setProgressBar. I ended up disabling the whole method on API >= 21.

For API >= 21, I use SupperPuccio solution.

Solution 24 - Android

The rating bar is used automatically at run time for change color on touch star.

First add style in app\src\main\res\values\styles.xml file:

<style name="RatingBar" parent="Theme.AppCompat">
    <item name="colorControlNormal">@android:color/darker_gray</item>
    <item name="colorControlActivated">@color/com_facebook_blue</item>
</style>

Then your rating bar add theme like this:

<RatingBar
   android:id="@+id/rating"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:numStars="5"
   android:stepSize="1"
   android:theme="@style/RatingBar"/>

Solution 25 - Android

  1. declare this xml

       <com.example.android.custom_ratingbar.CustomRatingBar
        android:id="@+id/coloredRatingBar5"
        style="@style/coloredRatingBarStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
         
         />
       </LinearLayout>
    
  2. in style.xml

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class CustomRatingBar extends View{

    private static final String TAG="ColoredRatingBar";
    private static final int NORMAL = 0;
    private static final int SMALL = 1;

    Bitmap[] drawables;
    Bitmap progressBackground;
    Context mContext;
    private int mNumStars =9;
    private float mRating =0;
    private boolean mIndicator;
    private float slidePosition;
    private int mType;

    /**
     * A callback that notifies clients when the rating has been changed. This
     * includes changes that were initiated by the user through a touch gesture
     * or arrow key/trackball as well as changes that were initiated
     * programmatically.
     */
    public interface OnRatingBarChangeListener {

        /**
         * Notification that the rating has changed. Clients can use the
         * fromUser parameter to distinguish user-initiated changes from those
         * that occurred programmatically. This will not be called continuously
         * while the user is dragging, only when the user finalizes a rating by
         * lifting the touch.
         *
         * @param ratingBar The RatingBar whose rating has changed.
         * @param rating The current rating. This will be in the range
         *            0..numStars.
         * @param fromUser True if the rating change was initiated by a user's
         *            touch gesture or arrow key/horizontal trackbell movement.
         */
        void onRatingChanged(CustomRatingBar ratingBar, float rating, boolean fromUser);

    }

    private OnRatingBarChangeListener mOnRatingBarChangeListener;

    public CustomRatingBar(Context context) {
        this(context, null);
    }
    public CustomRatingBar(Context context, AttributeSet attrs) {
        this(context, attrs,0);//R.attr.coloredRatingBarStyle
    }

    public CustomRatingBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomRatingBar,defStyle, 0);
        final boolean indicator = a.getBoolean(R.styleable.CustomRatingBar_indicator, false);
        final float rating = a.getFloat(R.styleable.CustomRatingBar_setrating, -1);
        final int type = a.getInt(R.styleable.CustomRatingBar_type, 0);
        a.recycle();

        setIndicator(indicator);
        setRating(rating);
        setType(type);
        init(context);
    }

    public int getType() {
        return mType;
    }

    public void setType(int type) {
        this.mType = type;
    }

    private void init(Context context) {
        mContext = context;
        Resources res = getResources();
        if(mType==SMALL){
            drawables = new Bitmap[]{BitmapFactory.decodeResource(res, R.drawable.rating_inactive),BitmapFactory.decodeResource(res, R.drawable.rating_active)};
            progressBackground = BitmapFactory.decodeResource(res, R.drawable.rating_inactive);
        }else{
            drawables = new Bitmap[]{BitmapFactory.decodeResource(res, R.drawable.rating_inactive),BitmapFactory.decodeResource(res, R.drawable.rating_active)};
            progressBackground = BitmapFactory.decodeResource(res, R.drawable.rating_inactive);
        }
        
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //draw empty stars bg
        for(int i=0;i< mNumStars;i++){
            drawStar(canvas,i);
        }

    }


    private void drawStar(Canvas canvas, int position) {
        float fraction = mRating -(position);
        Bitmap ratedStar1 = getRatedStar();
        Paint paint=getPaint(position);
        int division=getSize();
        Bitmap ratedStar=null;
        Bitmap emptyStar=null;
       if(!isInEditMode()){
        ratedStar=Bitmap.createScaledBitmap(ratedStar1, division, division, false);
        emptyStar=Bitmap.createScaledBitmap(progressBackground, division, division, false);
       }
        if((position)< mRating){
        	if(!isInEditMode()){
           canvas.drawBitmap(ratedStar,(position* division),0,paint);
        	}
            
        } else{
        	
            	if(!isInEditMode()){
              canvas.drawBitmap(emptyStar,(position*division),0,null);
            	
            }
        }


    }
    private int getSize(){
    	return (getWidth()/mNumStars);
    }

    private Bitmap getRatedStar() {
     
    	if(mRating==0){
    		return drawables[0];
    	}
    	else{
    		return drawables[1];
    	}
    }
    
    private Paint getPaint(int position){
    	int value=(255*(position+1))/mNumStars;
    	String hexString=Integer.toHexString(value).equals("0")?"00":Integer.toHexString(value);
    	String hexvalue="#"+hexString+"000000";//FEE98E
    	//Log.e("TAG", position+"/"+value+"/"+hexvalue);
    	
    	Paint paint=new Paint();
    
    	paint.setColor(Color.parseColor(hexvalue));
    	
    	return paint;
    }

    public int getNumStars() {
        return mNumStars;
    }

    public void setNumStars(int numStars) {
        this.mNumStars = numStars;
    }

    public float getRating() {
        return mRating;
    }

    public void setRating(float rating) {
        setRating(rating,false);
    }

    void setRating(float rating,boolean fromUser) {
        if(rating>mNumStars){
            this.mRating = mNumStars;
        }
        this.mRating = rating;
        invalidate();
        dispatchRatingChange(fromUser);
    }

    public boolean isIndicator() {
        return mIndicator;
    }

    public void setIndicator(boolean indicator) {
        this.mIndicator = indicator;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (progressBackground != null) {

            final int width = progressBackground.getWidth() * mNumStars;
            final int height = progressBackground.getHeight();
            
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            Bitmap emptyStar=Bitmap.createScaledBitmap(progressBackground, widthSize/mNumStars, widthSize/mNumStars, false);
            int heightSize = emptyStar.getHeight();
            
            setMeasuredDimension(resolveSizeAndState(widthSize, widthMeasureSpec, 0),
                    resolveSizeAndState(heightSize, heightMeasureSpec, 0));
        }
        else{
        	  int desiredWidth = 100;
      	    int desiredHeight = 50;

      	    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
      	    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
      	    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
      	    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

      	    int width;
      	    int height;

      	    //Measure Width
      	    if (widthMode == MeasureSpec.EXACTLY) {
      	        //Must be this size
      	        width = widthSize;
      	    } else if (widthMode == MeasureSpec.AT_MOST) {
      	        //Can't be bigger than...
      	        width = Math.min(desiredWidth, widthSize);
      	    } else {
      	        //Be whatever you want
      	        width = desiredWidth;
      	    }

      	    //Measure Height
      	    if (heightMode == MeasureSpec.EXACTLY) {
      	        //Must be this size
      	        height = heightSize;
      	    } else if (heightMode == MeasureSpec.AT_MOST) {
      	        //Can't be bigger than...
      	        height = Math.min(desiredHeight, heightSize);
      	    } else {
      	        //Be whatever you want
      	        height = desiredHeight;
      	    }

      	    //MUST CALL THIS
      	  setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, 0),resolveSizeAndState(height, heightMeasureSpec, 0));
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(mIndicator){
            return false;
        }

        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
            	slidePosition = getRelativePosition(event.getX());
            	
                int newRating = (int)(slidePosition>0?slidePosition+1:0) ;
                if(newRating>mNumStars){
                	newRating=mNumStars;
                }
                
             //   Log.e("TAG", ""+newRating);
                if (newRating != mRating) {
                    setRating(newRating,true);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
            default:
                break;
        }

        return true;
    }

    private float getRelativePosition(float x) {
    	Bitmap emptyStar=Bitmap.createScaledBitmap(progressBackground, getWidth()/mNumStars, getWidth()/mNumStars, false);
        int widthSize = emptyStar.getWidth();
      //  Log.e("TAG", widthSize+"/"+x);
    	 float position = x / widthSize;
       position = Math.max(position, 0);
       return Math.min(position, mNumStars);
    }

    /**
     * Sets the listener to be called when the rating changes.
     *
     * @param listener The listener.
     */
    public void setOnRatingBarChangeListener(OnRatingBarChangeListener listener) {
        mOnRatingBarChangeListener = listener;
    }

    /**
     * @return The listener (may be null) that is listening for rating change
     *         events.
     */
    public OnRatingBarChangeListener getOnRatingBarChangeListener() {
        return mOnRatingBarChangeListener;
    }

    void dispatchRatingChange(boolean fromUser) {
        if (mOnRatingBarChangeListener != null) {
            mOnRatingBarChangeListener.onRatingChanged(this, getRating(),
                    fromUser);
        }
    }
}


5) then in calling activity---

CustomRatingBar coloredRatingBar5=(CustomRatingBar)findViewById(R.id.coloredRatingBar5);
		coloredRatingBar5.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
			
			@Override
			public void onRatingChanged(CustomRatingBar ratingBar, float rating,boolean fromUser) {
				// TODO Auto-generated method stub
				Log.e("RATING", ""+rating);
				
			}
		});

6) rating active---take any image with dark color coz it will be used as color transparency for different rating

rating_inactive--take any image of same size of above image with light background..it will used when no rating is selected

Solution 26 - Android

A very easy way to change the border colour of the stars is using the xml parameter:

android:progressBackgroundTint=""

in the ratingBar view. The value should be a hexadecimal code for a color.

Solution 27 - Android

I was looking for a reliable method to do this all the way down to API 9 at least. The "casting to LayerDrawble" solution seemed like a risky solution to me, and when I tested it out on an Android phone on 2.3, it casted successfully but the call to DrawableCompat.setTint(...) did not have any effect.

The need to load drawable assets did not seem like a good solution to me either.

I decided to code my own solution which is a class extending AppCompatRatingBar, using a custom Drawable taking care of drawing the stars programmatically. It works perfectly for my needs, I'll post it in case it helps anyone:

https://gist.github.com/androidseb/2b8044c90a07c7a52b4bbff3453c8460

The link is easier because you can get the full file directly, but here is the full code just in case:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatRatingBar;
import android.util.AttributeSet;

/**
 * @author androidseb
 *         <p/>
 *         Extends AppCompatRatingBar with the ability to tint the drawn stars when selected, pressed and un-selected.
 *         Limitation: Only draws full stars.
 */
public class TintableRatingBar extends AppCompatRatingBar {
	private TintableRatingBarProgressDrawable progressDrawable;

	public TintableRatingBar(final Context context) {
		super(context);
		init();
	}

	public TintableRatingBar(final Context context, final AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public TintableRatingBar(final Context context, final AttributeSet attrs, final int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init();
	}

	private void init() {
		progressDrawable = new TintableRatingBarProgressDrawable();
		setProgressDrawable(progressDrawable);
	}

	public void setCustomTintColors(final int _uncheckedColor, final int _pressedColor, final int _checkedColor) {
		progressDrawable.setRatingMaxLevelValue(getMax() * 1000);
		progressDrawable.setUnCheckedColor(_uncheckedColor);
		progressDrawable.setPressedColor(_pressedColor);
		progressDrawable.setCheckedColor(_checkedColor);
		invalidate();
	}

	public class TintableRatingBarProgressDrawable extends Drawable {
		private static final int STAR_COUNT = 5;
		private static final int STAR_BRANCHES_COUNT = 5;

		/** Sets the max level value: if the level is at the max, then all stars are selected. */
		private int ratingMaxLevelValue = 10000;
		/** Color to be painted for unselected stars */
		private int uncheckedColor = Color.GRAY;
		/** Color to be painted for unselected stars when the ratingbar is pressed */
		private int pressedColor = Color.CYAN;
		/** Color to be painted for selected stars */
		private int checkedColor = Color.BLUE;

		@Override
		public void setAlpha(final int _i) {
		}

		@Override
		public void setColorFilter(final ColorFilter _colorFilter) {
		}

		@Override
		public boolean isStateful() {
			return true;
		}

		@Override
		public boolean setState(final int[] stateSet) {
			final boolean res = super.setState(stateSet);
			invalidateSelf();
			return res;
		}

		@Override
		public int getOpacity() {
			return 255;
		}

		public void setRatingMaxLevelValue(final int _ratingMaxLevelValue) {
			ratingMaxLevelValue = _ratingMaxLevelValue;
		}

		public void setUnCheckedColor(final int _uncheckedColor) {
			uncheckedColor = _uncheckedColor;
		}

		public void setPressedColor(final int _pressedColor) {
			pressedColor = _pressedColor;
		}

		public void setCheckedColor(final int _checkedColor) {
			checkedColor = _checkedColor;
		}

		@Override
		public void draw(final Canvas _canvas) {
			boolean pressed = false;
			for (int i : getState()) {
				if (i == android.R.attr.state_pressed) {
					pressed = true;
				}
			}

			final int level = (int) Math.ceil(getLevel() / (double) ratingMaxLevelValue * STAR_COUNT);
			final int starRadius = Math.min(getBounds().bottom / 2, getBounds().right / STAR_COUNT / 2);

			for (int i = 0; i < STAR_COUNT; i++) {
				final int usedColor;
				if (level >= i + 1) {
					usedColor = checkedColor;
				} else if (pressed) {
					usedColor = pressedColor;
				} else {
					usedColor = uncheckedColor;
				}
				drawStar(_canvas, usedColor, (i * 2 + 1) * starRadius, getBounds().bottom / 2, starRadius,
					STAR_BRANCHES_COUNT);
			}
		}

		private void drawStar(final Canvas _canvas, final int _color, final float _centerX, final float _centerY,
			final float _radius, final int _branchesCount) {
			final double rotationAngle = Math.PI * 2 / _branchesCount;
			final double rotationAngleComplement = Math.PI / 2 - rotationAngle;
			//Calculating how much space is left between the bottom of the star and the bottom of the circle
			//In order to be able to center the star visually relatively to the square when drawn
			final float bottomOffset = (float) (_radius - _radius * Math.sin(rotationAngle / 2) / Math.tan(
				rotationAngle / 2));
			final float actualCenterY = _centerY + (bottomOffset / 2);
			final Paint paint = new Paint();
			paint.setColor(_color);
			paint.setStyle(Style.FILL);
			final Path path = new Path();
			final float relativeY = (float) (_radius - _radius * (1 - Math.sin(rotationAngleComplement)));
			final float relativeX = (float) (Math.tan(rotationAngle / 2) * relativeY);
			final PointF a = new PointF(-relativeX, -relativeY);
			final PointF b = new PointF(0, -_radius);
			final PointF c = new PointF(relativeX, -relativeY);
			path.moveTo(_centerX + a.x, actualCenterY + a.y);
			_canvas.save();
			for (int i = 0; i < _branchesCount; i++) {
				path.lineTo(_centerX + b.x, actualCenterY + b.y);
				path.lineTo(_centerX + c.x, actualCenterY + c.y);
				rotationToCenter(b, rotationAngle);
				rotationToCenter(c, rotationAngle);
			}
			_canvas.drawPath(path, paint);
			_canvas.restore();
		}

		private void rotationToCenter(final PointF _point, final double _angleRadian) {
			final float x = (float) (_point.x * Math.cos(_angleRadian) - _point.y * Math.sin(_angleRadian));
			final float y = (float) (_point.x * Math.sin(_angleRadian) + _point.y * Math.cos(_angleRadian));
			_point.x = x;
			_point.y = y;
		}
	}
}

Solution 28 - Android

A bit late answer but i hope it will help some folks.

<RatingBar
         android:id="@+id/rating"
         style="@style/Base.Widget.AppCompat.RatingBar.Small"
         android:theme="@style/WhiteRatingStar"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_below="@+id/profil_name"
         android:layout_centerHorizontal="true"
         android:layout_marginLeft="@dimen/dimen_4"
         android:rating="3" />

And here is what the WhiteRatingStar looks like

<style name="WhiteRatingStar" parent="Base.Widget.AppCompat.RatingBar.Small">
     <item name="colorAccent">@android:color/white</item>
</style>

With this the stars will be coloured in white for example.

Solution 29 - Android

Solution 30 - Android

As the previous answer implies, it is not easy to change the color of the ratingbar. The stars are not programmatically drawn, they are images with fixed size and specific color gradients. To change the color you have to create your own star images with different colors then proceed to create your own drawable XML resource and pass it to the ratingsBar class using setProgressDrawable(Drawable d) or XML attribute android:progressDrawable.

Solution 31 - Android

Just edit or add

<color name="colorAccent">#3b71c7</color>

in your resource value folder

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiond-manView Question on Stackoverflow
Solution 1 - AndroidAlexView Answer on Stackoverflow
Solution 2 - AndroidMirek MichalakView Answer on Stackoverflow
Solution 3 - AndroidVishal KumarView Answer on Stackoverflow
Solution 4 - AndroidmatteopucView Answer on Stackoverflow
Solution 5 - AndroidlgvalleView Answer on Stackoverflow
Solution 6 - AndroidYuriy VinogradovView Answer on Stackoverflow
Solution 7 - AndroidCommonsWareView Answer on Stackoverflow
Solution 8 - AndroidYoungDinosaurView Answer on Stackoverflow
Solution 9 - AndroidboxView Answer on Stackoverflow
Solution 10 - AndroidDan Dar3View Answer on Stackoverflow
Solution 11 - AndroidRahulView Answer on Stackoverflow
Solution 12 - AndroidhidroView Answer on Stackoverflow
Solution 13 - AndroidletrounetView Answer on Stackoverflow
Solution 14 - AndroidMehatabView Answer on Stackoverflow
Solution 15 - Android4ndro1dView Answer on Stackoverflow
Solution 16 - AndroidsplangiView Answer on Stackoverflow
Solution 17 - AndroidSibasishView Answer on Stackoverflow
Solution 18 - AndroidArbiturView Answer on Stackoverflow
Solution 19 - AndroidKuldeep SakhiyaView Answer on Stackoverflow
Solution 20 - AndroidHai RomView Answer on Stackoverflow
Solution 21 - AndroidVimesh PkView Answer on Stackoverflow
Solution 22 - AndroidHardik4560View Answer on Stackoverflow
Solution 23 - AndroidJDenaisView Answer on Stackoverflow
Solution 24 - AndroidNavadip PatelView Answer on Stackoverflow
Solution 25 - AndroidamitView Answer on Stackoverflow
Solution 26 - AndroidPau Arlandis MartinezView Answer on Stackoverflow
Solution 27 - AndroidandroidsebView Answer on Stackoverflow
Solution 28 - AndroidMartial KonviView Answer on Stackoverflow
Solution 29 - AndroidJatin BansalView Answer on Stackoverflow
Solution 30 - AndroidDavidView Answer on Stackoverflow
Solution 31 - AndroidAkshay SahaiView Answer on Stackoverflow