Android RatingBar меняет цвет звезды - программирование

Android RatingBar меняет цвет звезды

Как изменить цвет звезд и как изменить размер звезд?

4b9b3361

Ответ 1

Шаг №1: Создайте свой собственный стиль, клонировав один из существующих стилей (от $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml), поместив его в свой собственный проект styles.xml и ссылаясь на него при добавлении виджета в макет.

Шаг №2: Создайте собственные XML-ресурсы LayerDrawable для RatingBar, указывая на соответствующие изображения, которые будут использоваться для панели. Оригинальные стили укажут вам на существующие ресурсы, с которыми вы можете сравнить. Затем настройте свой стиль, чтобы использовать собственные ресурсы LayerDrawable, а не встроенные.

Ответ 2

В этом блоге немного сложнее, я использовал аналогичный, но более простой способ. Вам нужны 3-звездочные изображения (red_star_full.png, red_star_half.png и red_star_empty.png) и один xml, что все.

Поместите эти 3 изображения в res/drawable.

Добавьте следующий рейтингbar_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"/>

Что это.

Ответ 3

Попробуйте, если вы хотите изменить цвет:

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

Ответ 4

Самый простой способ, который работал у меня... если вы расширяете AppCompat Activity

В вашем build.gradle добавьте последнюю библиотеку appcompat.

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>  

Примените этот стиль к вашему RatingBar через атрибут android: theme.

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

Ответ 5

2015 Update

Теперь вы можете использовать DrawableCompat, чтобы отобразить все виды чертежей. Например:

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

Это обратно совместимо с API 4

Ответ 6

Если вы хотите изменить цвет для всех состояний звезд, вы меня используете:

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

Ответ 7

С API 21 очень легко изменить цвет звезд с помощью этих трех строк кода:

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

Делая это так, вы измените:

  • цвет закрашенных звездочек (progressTint)
  • цвет незаполненных звездочек (progressBackgroundTint)
  • и цвет границы (secondProgressTint) звезд

Ответ 8

Решения, опубликованные Alex и CommonsWares, верны. Одна вещь, о которой 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

Ответ 9

Итак, я боролся с этой проблемой в течение двух часов, и у меня появилось рабочее решение для всех версий 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);
    }
}

Вы вызываете метод с этим порядком 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));

ПРИМЕЧАНИЕ. Также необходимо указать атрибуты "max" и "numStars" в XML, иначе половина звезд не отображается.

Ответ 10

Теперь вы можете использовать DrawableCompat из AppCompat v22.1.0 и далее, чтобы динамически отображать все виды чертежей, полезно, когда вы поддерживаете несколько темы с одним набором чертежей. Например:

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 в блоге Библиотеки поддержки v22.1.0

Для фактического размера и формы вам нужно будет определить новые стили и списки слоев для соответствующего размера, как уже было сказано выше.

Ответ 11

Использовать атрибут android:theme:

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

Ответ 12

Только для изменения цвета панели рейтинга из xml: -

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

Ответ 13

Чтобы изменить цвет, который вам нужно просто установить, установите параметр 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"
       />

Для размера свойства style.

Ответ 14

Самый простой способ:

android:progressTint="@color/color"

Ответ 15

Построение ответа @lgvalle.

2015 Update

Теперь вы можете использовать DrawableCompat, чтобы отображать все типы чертежей. Например:

Ожидаемый прогресс = ratingBar.getProgressDrawable();    DrawableCompat.setTint(прогресс, цвет .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));

Это сохранит цвета шагов фракции.

Ответ 16

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

используйте свой собственный цвет

Ответ 17

С добавлением нового стиля вы можете использовать цвет оттенка в 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"/>

Ответ 18

Работает для 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

Ответ 19

Простое решение, используйте AppCompatRatingBar и его метод setProgressTintList для достижения этой цели, см. Этот ответ для справки.

Ответ 20

Я решаю эту проблему следующим образом:

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

Ответ 21

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

для меня его работа....

Ответ 22

Я нашел простое решение для изменения цвета звезды в соответствии с вашей темой.

Перейти на этот сайт: http://android-holo-colors.com/

Выберите цвет своей темы и создайте свои звездообразные изображения.

Ответ 23

Используя приведенные выше ответы, я создал быстрый статический метод, который можно легко повторить. Он направлен только на тонирование цвета прогресса активированных звезд. Звезды, которые не активированы, остаются серыми.

    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, чтобы он был обратно совместим.

EDIT: этот метод не работает в API21 (перейдите к примеру). Вы получаете исключение NullPointerException при вызове setProgressBar. В итоге я отключил весь метод API >= 21.

Для API >= 21 я использую решение SupperPuccio.

Ответ 24

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) рейтинг активен --- возьмите любое изображение с темным цветом coz, оно будет использоваться как прозрачность цвета для разного рейтинга

rating_inactive - возьмите любое изображение с таким же размером выше изображения со светом фона.. оно будет использоваться, когда не будет выбран рейтинг

Ответ 25

Очень простой способ изменить цвет рамки звезд - это использовать параметр xml:

android:progressBackgroundTint=""

в рейтинге. Значение должно быть шестнадцатеричным кодом для цвета.

Ответ 26

Я искал надежный способ сделать это вплоть до API 9 по крайней мере. Решение "casting to LayerDrawble" показалось мне рискованным решением, и когда я протестировал его на телефоне Android 2.3, он успешно прошел успешно, но вызов 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;
        }
    }
}

Ответ 27

Немного поздний ответ, но я надеюсь, что это поможет некоторым людям.

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

И вот что выглядит WhiteRatingStar

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

При этом звезды будут окрашены в белый цвет, например.

Ответ 28

Строка рейтинга используется автоматически во время выполнения для изменения цвета на сенсорной звезде.

Сначала добавьте стиль в файл app\src\main\res\values ​​\ 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"/>

Ответ 30

Как следует из предыдущего ответа, изменить цвет панели оценки нелегко. Звезды не программно рисуются, это изображения с фиксированным размером и особыми цветовыми градиентами. Чтобы изменить цвет, вам нужно создать свои собственные звездообразные изображения с разными цветами, затем приступайте к созданию собственного ресурса XML-ресурса и передайте его классу ratingBar с помощью setProgressDrawable (Drawable d) или атрибута XML android: progressDrawable.