Android RatingBar更改星星颜色

Android RatingBar更改星星颜色,android,rating,Android,Rating,如何更改星星的颜色和大小?步骤1:通过克隆一个现有样式(从$ANDROID\u HOME/platforms/$SDK/data/res/values/styles.xml),将其放在您自己项目的styles.xml中,并在将小部件添加到布局时引用它,创建您自己的样式 步骤2:为分级栏创建自己的LayerDrawableXML资源,指向要用于分级栏的适当图像。原始样式将指向可以比较的现有资源。然后,调整您的样式以使用您自己的图层可绘制资源,而不是内置资源。正如前面的答案所暗示的,更改分级栏的颜色

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

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


步骤2:为
分级栏
创建自己的
LayerDrawable
XML资源,指向要用于分级栏的适当图像。原始样式将指向可以比较的现有资源。然后,调整您的样式以使用您自己的
图层可绘制资源,而不是内置资源。

正如前面的答案所暗示的,更改分级栏的颜色并不容易。星星不是以编程方式绘制的,它们是具有固定大小和特定颜色渐变的图像。要更改颜色,您必须使用不同的颜色创建自己的星形图像,然后继续创建自己的可绘制XML资源,并使用setProgressDrawable(drawable d)或XML属性android:progressDrawable将其传递给ratingsBar类。

在上述博客中有点复杂,我使用了类似但更简单的方法。 您确实需要3个星形图像(red_star_full.png、red_star_half.png和red_star_empty.png)和一个xml,仅此而已

将这3幅图像设置为res/drawable

将以下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和Commonware发布的解决方案是正确的。不过,安卓从未提及的一件事是不同密度的像素大小是否合适。以下是基于光晕光的每个密度所需的尺寸

小星星

mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px
mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px
mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
中星级

mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px
mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px
mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
大星星

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年更新

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

Drawable progress = ratingBar.getProgressDrawable();
DrawableCompat.setTint(progress, Color.WHITE);
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的,现在您可以从AppCompat v22.1.0开始使用它动态着色所有类型的可绘制内容,当您使用一组可绘制内容支持多个主题时非常有用。例如:

Drawable progress = ratingBar.getProgressDrawable();
DrawableCompat.setTint(progress, Color.WHITE);
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 Banes在

对于实际的大小和形状,您需要定义一个新的样式和图层列表,以获得合适的大小,其他人已经在上面给出了回答。

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

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

假的
小的
(三)

导入android.content.Context;
导入android.content.res.Resources;
导入android.content.res.TypedArray;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.util.AttributeSet;
导入android.view.MotionEvent;
导入android.view.view;
公共类CustomRatingBar扩展视图{
私有静态最终字符串TAG=“ColoredRatingBar”;
专用静态最终int-NORMAL=0;
私有静态final int SMALL=1;
位图[]可绘制;
位图背景;
语境;
私有int mNumStars=9;
私有浮点数=0;
专用布尔值指示器;
私人浮动席位;
私有int-mType;
/**
*当评级更改时通知客户端的回调
*包括用户通过触摸手势发起的更改
*或箭头键/轨迹球以及启动的更改
*以编程方式。
*/
公共接口OnRatingBarChangeListener{
/**
*通知分级已更改。客户端可以使用
*fromUser参数以区分用户发起的更改和
*以编程方式发生的。将不会连续调用
*当用户拖动时,仅当用户通过
*解除接触。
*
*@param ratingBar评级已更改的评级栏。
*@param rating当前额定值。这将在范围内
*0..numStars。
*@param fromUser True,如果评级更改是由用户的
*触摸手势或箭头键/水平履带铃移动。
*/
void onRatingChanged(自定义栏ratingBar、浮动评级、布尔值fromUser);
}
专用OnRatingBarChangeListener mOnRatingBarChangeListener;
公共自定义栏(上下文){
这个(上下文,空);
}
公共自定义栏(上下文、属性集属性){
this(context,attrs,0);//R.attr.coloredRatingBarStyle
}
公共自定义栏(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
TypedArray a=上下文。获取样式属性(attrs,R.styleable.CustomRatingBar,defStyle,0);
最终布尔指示符=a.getBoolean(R.styleable.CustomRatingBar_指示符,false);
最终浮动评级=a.getFloat(R.styleable.CustomRatingBar_setrating,-1);
final int type=a.getInt(R.styleable.CustomRatingBar_type,0);
a、 回收();
设置指示器(指示器);
设定额定值(额定值);
setType(类型);
init(上下文);
}
公共int getType(){
返回mType;
}
公共void集合类型(int类型){
this.mType=type;
}
私有void init(上下文){
mContext=上下文;
Resources res=getResources();
如果(mType==小){
drawables=新位图[]{BitmapFactory.decodeResource(res,R.drawable.rating_inactive),BitmapFactory.decodeResource(res,R.drawable.rating_active)}
<style name="Theme.Rating" parent="Theme.AppCompat.Light">
    <item name="colorAccent">@color/rating</item>
</style>
<android.support.v7.widget.AppCompatRatingBar
    android:theme="@style/Theme.Rating"
    android:numStars="5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
dependencies {  
    compile 'com.android.support:appcompat-v7:X.X.X' // where X.X.X version
}
public class MainActivity extends AppCompatActivity {  
    ...
}
<style name="RatingBar" parent="Theme.AppCompat">  
    <item name="colorControlNormal">@color/indigo</item>
    <item name="colorControlActivated">@color/pink</item>
</style>  
<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"/>
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));
RatingBar mRating=(RatingBar)findViewById(R.id.rating);
 LayerDrawable layerDrawable=(LayerDrawable)mRating.getProgressDrawable();
 layerDrawable.getDrawable(2).setColorFilter(Color.parseColor
 ("#32CD32"),    PorterDuff.Mode.SRC_ATOP);
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
                    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"/>
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>
<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"