Classificação do AndroidBar alterar as cores das estrelas [fechado]


141

Como posso alterar as cores e o tamanho das estrelas?


Eu acho que você tem que criar o seu próprio bar classificação personalizada se você quiser fazer isso
Donal Rafferty

Eu escrevi um post descrevendo como alterar imagens RatingBar: kozyr.zydako.net/2010/05/23/pretty-ratingbar Ele também mostra onde você pode especificar o tamanho da imagem ...
Kozyr

Eu esperava que esta pergunta fosse para barra de classificação multicolorida, como mostrado em sites, não consegui encontrar uma para mim. Eu mesmo criei uma implementação simples github.com/codebreaker/coloredratingbar-android . Espero que isto seja útil a alguém.
Jaga6

Respostas:


26

Etapa 1: Crie seu próprio estilo, clonando um dos estilos existentes (de $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml), colocando-o no seu próprio projeto styles.xmle fazendo referência a ele quando você adiciona o widget a um layout.

Etapa 2: crie seus próprios LayerDrawablerecursos XML para o RatingBar, apontando para as imagens apropriadas a serem usadas na barra. Os estilos originais apontarão para os recursos existentes com os quais você pode comparar. Em seguida, ajuste seu estilo para usar seus próprios LayerDrawablerecursos, em vez dos recursos internos.


1
Conforme a etapa 2, isso não funciona para dispositivos Samsung 3 ou alguns outros, não é necessário ser um LayerDrawable. Veja aqui para informações: stackoverflow.com/questions/30266334/…
Kenny

6
Use android: progressTint = "@ color / yellow". Veja a resposta de @superpuccio.
Vincent

2
progressTint suportado apenas acima do nível 21 api
Yogesh Rathi 04/03


120

É um pouco complicado no blog mencionado, usei uma maneira semelhante, mas mais simples. Você precisa de imagens de 3 estrelas (red_star_full.png, red_star_half.png e red_star_empty.png) e um xml, só isso.

Coloque essas 3 imagens em res / drawable.

Coloque aqui a seguinte 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>

e, finalmente, diga à sua definição da barra de classificação para usar isso, ou seja,

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

É isso aí.


3
Oi Alex, eu tentei esta solução, mas quando tento definir a classificação para algo como 1.1, 1.2, etc ... é exibido como 1.5. Eu tirei imagens de três estrelas, uma vazia, uma metade cheia e uma cheia. Eu presumo que é suposto interpolar entre eles para obter os componentes fracionários, só estou me perguntando se alguém mais teve o mesmo problema ou estou fazendo algo visivelmente errado?
Graham Baitson

Você pode por favor me dizer sobre as imagens que devemos usar o tempo suas imagens e tamanho das imagens coloridas de im não capaz de resolver isso ...
Prithviraj Shiroor

1
Todo mundo vê a resposta da atualização de 2015 abaixo! É muito mais fácil e mais simples!
21815 katie

Essa resposta ainda oferece mais flexibilidade sobre os diferentes estados das estrelas.
Tom Brinkkemper

Por que estou recebendo linhas verticais abaixo das estrelas? Tentei definir o estilo personalizado, especificando a altura, mas ainda há linhas verticais abaixo das estrelas no meu AVD.
Aleksandar

93

Tente isso, se você quiser apenas mudar de cor:

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

1
O que exatamente PorterDuff.Mode.SRC_ATOPsignifica ou faz?
Zapnologica

5
Não funciona na API 5.0 e superior. Precisa:Drawable stars = rb.getProgressDrawable(); stars.setTint( Color.YELLOW );
zyamys

@zyamys Esta realmente é uma porcaria = (método A para "versões superiores" e um outro método para versões mais antigas é necessário?
Daniela Morais

1
Funciona apenas para uma precisão de 0,5. Caso contrário (precisão <0,5) a sobreposição fica estranho e parece que a cor azul ainda está com uma precisão de 0,5, enquanto o amarelo é preciso
Teo Inke

1
Aviso: falha em dispositivos pré-lolipop. Vá com a resposta aceita.
blockwala

70

A maneira mais fácil que funcionou para mim ... se você estiver estendendo a Atividade AppCompat

Em seu build.gradle, adicione a biblioteca appcompat mais recente.

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

Faça sua atividade estender android.support.v7.app.AppCompatActivity

public class MainActivity extends AppCompatActivity {  
    ...
}

Declare o estilo customizado em seu arquivo styles.xml.

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

Aplique esse estilo à sua RatingBar via atributo 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"/>

3
Obrigado @Vishal Kumar. Eu tentei no Kitkat 4.4.4 (Samsung S3 neo) e Marshmallow 6.0.1 (Samsung Galaxy On Nxt), funcionou. Mas não houve sucesso no Lollipop 5.1 (Micromax). Para o Lollipop, usei o atributo "android: progressTint" no RatingBar e, sim, ele funciona.
Prashant

Essa é a melhor solução.
Arhat Baid

Essa deve ser a resposta correta selecionada.
Hampel Előd 29/11

1
essa é a melhor solução. Se você quiser alterar o tamanho da estrela, poderá usar style="?android:ratingBarStyleSmall"juntos.
André Luiz Reis

@ AndréLuizReis <style name="RatingBarSmallTheme" parent="Theme.AppCompat"> <item name="colorControlNormal">@color/colorOrangeNormal</item> <item name="colorControlActivated">@color/colorOrangeActivated</item> <item name="ratingBarStyle">@style/Widget.AppCompat.RatingBar.Small</item> </style> e sua classificaçãoBar android:theme="@style/RatingBarSmallTheme"
Zakhar Rodionov

47

Atualização de 2015

Agora você pode usar DrawableCompat para colorir todos os tipos de drawables. Por exemplo:

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

Isso é compatível com versões anteriores até API 4


Não se esqueça de colocar o drawable de volta na barra de classificação.
Squeeish 17/05/15

15
Isso tinge o desenho inteiro em uma cor, o que torna muito difícil distinguir as estrelas vazias.
blueice

Isso funciona apenas com a biblioteca de suporte do Android> = 22 e não com a biblioteca de suporte <22.
Raghav Sharma

2
Desenha 5 estrelas coloridas, não 3.5.
CoolMind

1
Gostaria apenas de cercar que, com if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {}uma vez que está trabalhando por padrão de API 22.
Yoann Hercouet

38

A partir da API 21 , é muito fácil alterar a cor das estrelas com estas três linhas de código:

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

Fazendo assim, você mudará:

  • a cor das estrelas preenchidas (progressTint)
  • a cor das estrelas não preenchidas (progressBackgroundTint)
  • e a cor da borda (secundáriasProgressTint) das estrelas

Em vez de 3,5, pinta 4 estrelas.
CoolMind

@CoolMind conjunto Android: stepSize: 1 em vez de 0,5
elemento

4
Como mudar a cor de uma estrela vazia?
winklerrr

@winklerrr você encontrou a solução como mudar a cor de uma estrela vazia.
Tarun Kumar

Não fazer mais verificações para encontrar uma solução
winklerrr

36

Se você deseja alterar a cor de todas as estrelas, declarei o meu uso:

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

Existe alguma maneira de definir a cor das estrelas com base nos dados buscados no banco de dados? Digamos que eu tenho 5 estrelas e os dados retornados do banco de dados foi 4. Então, ao invés de mudar todos os 5, eu só alterar o primeiro 4

1
getColor está obsoleto agora, alguma alternativa?
Manohar Reddy

2
Você pode encontrar respostas aqui stackoverflow.com/a/32202256/2513291 Por exemplo, este ContextCompat.getColor abordagem (contexto, R.color.color_name)
Yuriy Vinogradov

funciona bem, mas observe que, por algum motivo, a ordem é importante (2, depois 1 e depois 0). Eu tentei o inverso e isso levou a algumas falhas na interface do usuário na primeira vez que a cor foi alterada.
Simon Ninon

25

As soluções que Alex e CommonsWares publicaram estão corretas. Uma coisa sobre a qual o Android nunca fala é sobre tamanhos de pixels adequados para diferentes densidades. Aqui estão as dimensões necessárias para cada densidade com base na luz halo.

Estrela pequena

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

Estrela Média

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

Estrela grande

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

eu posso usar vectordrawble com estrelas
Mina Fawzy

24

Então, eu estou lutando com esse problema há duas horas e criei uma solução funcional para todas as versões da API, onde também são mostradas classificações de meia estrela.

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

Você chama o método com esta ordem de 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));

NOTA: Você também deve especificar os atributos "max" e "numStars" em XML, caso contrário, meias estrelas não serão exibidas.


a única maneira que funciona para mim no API19, mas eu não desisti de procurar uma maneira de fazer isso a partir de xml única T_T
Beeing Jk

@BeeingJk Se você criar uma exibição personalizada que estenda a RatingBar, poderá criar seus próprios atributos xml para especificar a cor da tonalidade. Você tem um único ponto de controle para definir a tonalidade e pode especificar a tonalidade em xml. Espero que ajude! Pode explicar mais se necessário
Forrest Bice

Mode.SRC_INou Mode.MULTIPLY?
Dr.jacky

12

Agora você pode usar o DrawableCompat a partir do AppCompat v22.1.0 para colorir dinamicamente todos os tipos de drawables, úteis quando você oferece suporte a vários temas com um único conjunto de drawables. Por exemplo:

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

Isso é compatível com a API 4. Consulte também a publicação no blog de Chris Banes em Support Libraries v22.1.0

Para o tamanho e a forma reais, você precisará definir um novo estilo e drawables de lista de camadas para o tamanho apropriado, como outros já responderam acima.


Drawables não são matrizes, como você está acessando o progresso [0]?
blueice

@blueice Você está arrependido, Drawable deve ser um LayerDrawable, corrigido agora, obrigado.
Dan Dar3

Ainda não pareceu funcionar para mim, acabei com o que Yuriy Vinogradov colocou em uma resposta diferente a essa pergunta e isso parece funcionar.
22615 blueice

Como mudar Drawable ao invés de mudar de cor?
Iman Marashi

@ImanMarashi Consulte a resposta baseada em XML de Alex acima, LayerDrawable.setDrawable (index, drawable) está disponível apenas a partir da API23.
Dan Dar3

10

Usar android:themeatributo:

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

9

Por apenas alterar a cor da barra de classificação de xml: -

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

ele não mudar de cor estrela vazia
Nainal

7

Para mudar a cor basta colocar o parâmetro 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"
       />

Para o tamanho da propriedade style.


só funciona em API 21 ou superior, graças
Junaid

5

A maneira mais simples:

android:progressTint="@color/color"

1
Observe que isso funciona apenas na API 21+
Ixx

4

Construindo a resposta da @ lgvalle.

Atualização de 2015

Agora você pode usar DrawableCompat para colorir todos os tipos de drawables. Por exemplo:

Progresso desenhável = ratingBar.getProgressDrawable (); DrawableCompat.setTint (progress, Color.WHITE); Isso é compatível com versões anteriores até 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));

Isso manterá as cores das etapas da fração.


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

use sua própria cor


4

Sem adicionar um novo estilo, você pode usar a cor da tonalidade dentro do 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"/>

3

Funciona para Android abaixo e acima da versão 21

Depois de algumas pesquisas, desenvolvi esse método para definir a tonalidade de fundo, a diferença de espaço (ex: meia estrela) e a cor da tonalidade da estrela.

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

3

Solução simples, use AppCompatRatingBar e seu método setProgressTintList para conseguir isso; consulte esta resposta para referência.


Isso funcionou para mim sob API 28 usando com.google.android.material: Material: 1.1.0-alpha02
Mark Lapasa

2

Eu resolvo esse problema da seguinte maneira:

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

Obrigado, funciona. Mas, para classificação fracionária, as estrelas são pintadas totalmente.
CoolMind

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

para mim está funcionando ....



1

Usando as respostas acima, criei um método estático rápido que pode ser facilmente reutilizado. Ele visa apenas colorir a cor do progresso das estrelas ativadas. As estrelas que não são ativadas permanecem cinza.

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

Basta passar sua barra de classificação e uma cor usando getResources().getColor(R.color.my_rating_color)

Como você pode ver, eu uso o DrawableCompat, por isso é compatível com versões anteriores.

EDIT: Este método não funciona na API21 (veja o porquê). Você acaba com um NullPointerException ao chamar setProgressBar. Acabei desativando todo o método na API> = 21.

Para API> = 21, eu uso a solução SupperPuccio.


java.lang.ClassCastException: android.support.v4.graphics.drawable.DrawableWrapperHoneycomb não pode ser convertido para android.graphics.drawable.LayerDrawable na pré-pirulito
Ishaan Garg

1
@IshaanGarg você está certo. Corri para o mesmo problema e atualizei meu método. Atualizei meu código para lidar com o caso. Eu não acho que é uma questão de versão para Android. Se você usar a versão menor da barra de classificação (com style = "? Android: attr / ratingBarStyleSmall"), o drawable retornado ainda será um LayoutDrawable.
JDenais

Sim, exatamente o que eu havia implementado, não deixe de usar AppCompatRatingBar. Embora eu não seja capaz de obter meia estrela ao pré-definir a classificação em XML / java. Classificação (3,5) mostra 4 estrelas completas
Ishaan Garg

1

A barra de classificação é usada automaticamente no tempo de execução para alterar a cor na estrela de toque.

Primeiro adicione estilo no arquivo 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>

Em seguida, sua barra de classificação adiciona um tema como este:

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

0

1) declarar este 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) em 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) classificação ativa --- tire qualquer imagem com cor escura, pois ela será usada como transparência de cores para classificações diferentes

rating_inactive - tira qualquer imagem do mesmo tamanho da imagem acima com fundo claro ... será usada quando nenhuma classificação for selecionada


0

Uma maneira muito fácil de alterar a cor da borda das estrelas é usar o parâmetro xml:

android:progressBackgroundTint=""

na visualização ratingBar. O valor deve ser um código hexadecimal para uma cor.


Eu não sei por que, mas parece que você só método afeta a fronteira das estrelas (a cor enchimento continua a ser a cor padrão)
superpuccio

Ok, você perdeu alguns parâmetros XML. Confira minha resposta aqui abaixo.
Superpuccio 01/07/2015

1
Você está certo. Eu não sei por que eu estava pensando que ele tinha problemas para mudar a cor da borda da estrela (talvez porque se eu tivesse o problema). Sua resposta é mais completa.
Pau Arlandis Martinez

0

Eu estava procurando por um método confiável para fazer isso até a API 9, pelo menos. A solução "transmitir para LayerDrawble" parecia uma solução arriscada para mim e, quando o testei em um telefone Android no 2.3, foi transmitida com sucesso, mas a chamada para DrawableCompat.setTint (...) não teve nenhum efeito.

A necessidade de carregar recursos extraíveis também não me pareceu uma boa solução.

Decidi codificar minha própria solução, que é uma classe que estende AppCompatRatingBar, usando um Drawable personalizado, cuidando de desenhar as estrelas programaticamente. Funciona perfeitamente para as minhas necessidades, postarei caso ajude alguém:

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

O link é mais fácil porque você pode obter o arquivo completo diretamente, mas aqui está o código completo, apenas no caso de:

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

0

Resposta um pouco tarde, mas espero que ajude algumas pessoas.

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

E aqui está a aparência do WhiteRatingStar

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

Com isso, as estrelas serão coloridas em branco, por exemplo.



-1

Como a resposta anterior indica, não é fácil alterar a cor da barra de classificação. As estrelas não são desenhadas programaticamente, são imagens com tamanho fixo e gradientes de cores específicos. Para alterar a cor, você deve criar suas próprias imagens de estrela com cores diferentes e, em seguida, criar seu próprio recurso XML desenhável e passá-lo para a classe ratingsBar usando o atributo setProgressDrawable (Drawable d) ou XML android: progressDrawable.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.