改变星星的颜色

如何改变星星的颜色和大小?

156293 次浏览

步骤 # 1: 创建您自己的样式,通过克隆一个现有的样式(来自 $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml) ,将其放在您自己的项目的 styles.xml中,并在将小部件添加到布局时引用它。

步骤 # 2: 为 RatingBar创建您自己的 LayerDrawable XML 资源,指向适当的图像以用于工具条。原始样式将指向可以比较的现有资源。然后,调整您的样式,使用您自己的 LayerDrawable资源,而不是内置的资源。

正如前面的答案所暗示的那样,改变分级条的颜色并不容易。这些星星不是以编程方式绘制的,它们是具有固定大小和特定颜色梯度的图像。为了改变颜色,你必须创建不同颜色的自己的星形图像,然后创建自己的可绘制 XML 资源,并使用 setProgressDrawable (Drawable d)或 XML 属性 android: Progress sDrawable 将其传递给 ratingsBar 类。

这是一个有点复杂的提到的博客,我已经使用了类似的,但更简单的方式。 您确实需要3个星型图像(red _ star _ full.png、 red _ star _ half.png 和 red _ star _ empty.png)和一个 xml,就这样。

把这3张图片放在可绘制的地方。

在那里放置下面的 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>

最后,告诉你的收视率定义使用这个,即。

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

就是这样。

Alex 和 Commons 发布的解决方案是正确的。但是 Android 从来没有提到一件事,那就是不同密度的像素尺寸是否合适。以下是基于晕光的每个密度所需要的尺寸。

小星星

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

中星

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

大星

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

试试这个,如果你只想改变颜色:

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

如果你想改变所有星星的颜色说明你我的用途:

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

2015年最新情况

现在你可以使用 DrawableCompat给所有类型的绘图工具着色。例如:

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

这是向后兼容到 API 4

现在您可以从 AppCompat v22.1.0开始使用 DrawableCompat来动态地着色所有类型的绘图,当您使用一组单独的绘图来支持多个主题时非常有用。例如:

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

这是向后兼容到 API 4的。也可以看看 Chris Bane 在 支援图书馆 v22.1.0上的博客文章

对于实际的大小和形状,您将需要定义一个新的样式和层列表绘制适当的大小,因为其他人已经回答了上面。

1)声明这个 xml

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:layout_marginBottom="20dp"
android:background="#323232"
android:gravity="center_horizontal">


<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)在 style.xml 中

<style name="coloredRatingBarStyleSmall">
<item name="indicator">false</item>
<item name="type">small</item>
</style>

3)

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)分级活动——-采取任何深色的图像,因为它将被用作不同分级的颜色透明度

评级 _ 非活动-采取任何图像的相同大小上面的图像与光背景。它将使用时,没有评级被选中

更改星星边框颜色的一个非常简单的方法是使用 xml 参数:

android:progressBackgroundTint=""

该值应该是一种颜色的十六进制代码。

从 API 21 开始,用这三行代码很容易改变星星的颜色:

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

这样做,你会改变:

  • 充满星星的颜色(渐进色)
  • 未填充的星星颜色(进展背景色)
  • 以及恒星的边界颜色(second daryProgressTint)

用于仅从 xml 改变 Rating bar 的颜色:-

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

建筑@lgvalle 的答案。

2015年最新情况

现在您可以使用 DrawableCompat 为所有类型的绘图工具着色。例如:

可绘制的进度 = ratingBar.getProgressDrawable () ; SetTint (进度,Color.WHITE) ; 这是向后兼容到 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));

这将保持分数步骤的颜色。

我找到了一个简单的解决方案,可以根据你的主题改变星星的颜色。

去这个网站: http://android-holo-colors.com/

选择您的主题颜色,并得到您的明星图像创建。

要改变颜色,只需要设置参数 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"
/>

样式属性的大小。

使用上面的答案,我创建了一个可以轻松重用的快速静态方法。它的目的只是为活动恒星着色。没有被激活的恒星仍然是灰色的。

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

只要通过你的评分条和颜色使用 getResources().getColor(R.color.my_rating_color)

如您所见,我使用 DrawableCompat,因此它是向后兼容的。

编辑: 这个方法在 API21上不起作用(想想为什么)。在调用 setProgressBar 时,最终会出现 NullPointerException。我最终在 API > = 21上禁用了整个方法。

对于 API > = 21,我使用 SupperPuccio 解决方案。

我这样解决这个问题:

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

使用 android:theme属性:

Xml

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

Xml

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

对我来说最简单的方法... 如果你扩展 AppCompat 活动

在 build.gradle 中添加最新的应用程序库。

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

让您的活动扩展 android.Support.v7.app. AppCompatActivity

public class MainActivity extends AppCompatActivity {
...
}

在 styles.xml 文件中声明自定义样式。

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

通过 android: theme 属性将此样式应用到 RatingBar。

<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"/>

所以我已经为这个问题奋斗了两个小时,我想出了一个适用于所有 API 版本的工作解决方案,其中也显示了半星级评级。

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

您可以使用以下绘图顺序调用该方法:

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

注意: 还必须在 XML 中指定属性“ max”和“ numStars”,否则不显示半星。

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

对我来说,它的工作... 。

我一直在寻找一种可靠的方法,至少可以一直做到 API 9。 对我来说,“向 LayerDrawble 进行强制转换”的解决方案似乎是一个危险的解决方案,当我在2.3版本的 Android 手机上进行测试时,它成功地进行了强制转换,但是对 DrawableCompat.setTint (...)的调用并没有产生任何效果。

对我来说,加载可提取资产的需要似乎也不是一个好的解决方案。

我决定编写自己的解决方案,这是一个类扩展 AppCompatRatingBar,使用自定义 Drawable 以编程方式绘制星星。它完美地满足了我的需求,我会把它贴出来,以防它对任何人都有帮助:

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

这个链接更简单,因为你可以直接获得完整的文件,但是以下是完整的代码,以防万一:

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;
}
}
}
<!--For rating bar -->
<style name="RatingBarfeed" parent="Theme.AppCompat">
<item name="colorControlNormal">@color/colorPrimary</item>
<item name="colorControlActivated">@color/colorPrimary</item>
</style>

用你自己的颜色

不需要添加新样式,就可以在 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"/>

适用于 Android 版本21以下及以上的版本

经过一些研究,我想出了这个方法来设置背景色彩,间隙色彩(例如: 半星)和星光色彩。

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

回答有点晚,但我希望它能帮助一些人。

<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" />

这就是白色评级之星的样子

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

例如,有了这个,星星就会变成白色。

在运行时自动使用等级条来更改触摸星星上的颜色。

在 app src main res value styles.xml 文件中首先添加样式:

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

然后你的评分条添加主题如下:

<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"/>

最简单的方法:

android:progressTint="@color/color"

只要编辑或添加

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

在您的资源值文件夹中

用这个链接

改变星星的颜色

设置你的风格内部值/风格(v-21) ;

简单的解决方案,用 AppCompatRatingBar及其 SetProgressTintList的方法来实现这一点,参见此 回答作参考。