Valutazione AndroidBar cambia i colori delle stelle [chiuso]


141

Come posso cambiare i colori e le dimensioni delle stelle?


Penso che devi creare la tua barra di valutazione personalizzata se vuoi farlo
Donal Rafferty

Ho scritto un post sul blog che descrive come modificare le immagini di RatingBar: kozyr.zydako.net/2010/05/23/pretty-ratingbar Mostra anche dove è possibile specificare la dimensione dell'immagine ...
kozyr

Speravo che questa domanda fosse per la barra di valutazione multicolore come mostrato nei siti Web, non sono riuscito a trovarne uno per me stesso. Ho creato personalmente una semplice implementazione github.com/codebreaker/coloredratingbar-android . Spero che questo aiuti qualcuno là fuori.
jaga,

Risposte:


26

Passaggio 1: crea il tuo stile personale, clonando uno degli stili esistenti (da $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml), inserendolo nel tuo progetto styles.xmle facendo riferimento a esso quando aggiungi il widget a un layout.

Step # 2: crea le tue LayerDrawablerisorse XML per RatingBar, indicando le immagini appropriate da usare per la barra. Gli stili originali ti indicheranno le risorse esistenti che puoi confrontare. Quindi, regola il tuo stile per utilizzare le tue LayerDrawablerisorse, piuttosto che quelle incorporate.


1
Come per il passaggio n. 2, questo non funziona per i dispositivi Samsung 3 o altri, non è necessario che sia un LayerDrawable. Vedi qui per informazioni: stackoverflow.com/questions/30266334/…
Kenny,

6
Usa Android: progressTint = "@ color / yellow". Vedi la risposta di @superpuccio.
Vincent,

2
progressTint è supportato solo al di sopra del livello 21 API
Yogesh Rathi

Questa è la soluzione migliore: stackoverflow.com/a/36297738/1935135
André Luiz Reis

120

È un po 'complicato nel blog menzionato, ho usato un modo simile ma più semplice. Sono necessarie 3 immagini a stella (red_star_full.png, red_star_half.png e red_star_empty.png) e un xml, tutto qui.

Metti queste 3 immagini in res / drawable.

Inserisci lì il seguente 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, infine, dire alla definizione della barra di valutazione di utilizzare questo, ad es

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

Questo è tutto.


3
Ciao Alex, ho provato questa soluzione ma quando provo a impostare la valutazione su qualcosa come 1.1, 1.2, ecc ... viene visualizzato come 1.5. Ho scattato 3 stelle, una vuota, una metà piena e una piena. Presumo che dovrebbe interpolare tra loro per ottenere i componenti frazionari, mi chiedo solo che qualcun altro abbia avuto lo stesso problema o sto facendo qualcosa di sensibilmente sbagliato?
Graham Baitson,

Potete per favore telefonarmi sulle immagini che dovremmo usare per il tempo, sono immagini colorate e dimensioni di immagini che non sono in grado di risolvere questo ...
Prithviraj Shiroor,

1
Tutti vedono la risposta dell'aggiornamento 2015 qui sotto! È molto più facile e più semplice!
Katie,

Questa risposta offre ancora maggiore flessibilità sui diversi stati delle stelle.
Tom Brinkkemper

Perché sto ottenendo linee verticali sotto le stelle? Ho provato a definire lo stile personalizzato, specificando l'altezza, ma ci sono ancora linee verticali sotto le stelle sul mio AVD.
Aleksandar,

93

Prova questo, se vuoi solo cambiare colore:

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

1
Cosa PorterDuff.Mode.SRC_ATOPsignifica esattamente o cosa fa?
Zapnologica,

5
Non funziona su API 5.0 e versioni successive. Esigenze:Drawable stars = rb.getProgressDrawable(); stars.setTint( Color.YELLOW );
zyamys,

@zyamys Questo fa davvero schifo = (È necessario un metodo per "versioni superiori" e un altro metodo per versioni precedenti?
Daniela Morais,

1
Funziona solo con una precisione di 0,5. Altrimenti (precisione <0,5) la sovrapposizione diventa strana e sembra che il colore blu sia ancora con una precisione di 0,5 mentre il giallo è preciso
Teo Inke,

1
Avvertenza: arresti anomali su dispositivi pre-lolipop. Vai con la risposta accettata.
Blockwala,

70

Il modo più semplice che ha funzionato per me ... se stai estendendo l'AppCompat Activity

Nel tuo build.gradle aggiungi l'ultima libreria di appcompat.

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

Rendi la tua attività estesa android.support.v7.app.AppCompatActivity

public class MainActivity extends AppCompatActivity {  
    ...
}

Dichiarare lo stile personalizzato nel file styles.xml.

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

Applica questo stile al tuo RatingBar tramite Android: attributo tema.

<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
Grazie @Vishal Kumar. L'ho provato su Kitkat 4.4.4 (Samsung S3 neo) e Marshmallow 6.0.1 (Samsung Galaxy On Nxt), ha funzionato. Ma nessun successo su Lollipop 5.1 (Micromax). Per Lollipop ho usato l'attributo "android: progressTint" in RatingBar e sì, funziona.
Prashant,

Questa è la soluzione migliore.
Arhat Baid

Questa dovrebbe essere la risposta corretta selezionata.
Hampel Előd,

1
Questa è la soluzione migliore Se vuoi cambiare la dimensione della stella, puoi usarla style="?android:ratingBarStyleSmall"insieme.
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 la tua valutazioneBar android:theme="@style/RatingBarSmallTheme"
Zakhar Rodionov

47

Aggiornamento 2015

Ora puoi usare DrawableCompat per colorare tutti i tipi di disegni. Per esempio:

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

Questo è retrocompatibile fino all'API 4


Non dimenticare di reimpostare il disegno sulla barra di valutazione.
spremere

15
Questo tinge l'intero disegno in un unico colore che rende le stelle vuote molto difficili da distinguere.
blueice l'

Funziona solo con la libreria di supporto Android> = 22 e non con la libreria di supporto <22.
Raghav Sharma,

2
Disegna 5 stelle colorate, non 3.5.
CoolMind

1
Lo circonderei solo if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {}perché funziona di default dall'API 22.
Yoann Hercouet,

38

Dall'API 21 in poi è molto facile cambiare il colore delle stelle con queste tre righe di codice:

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

In questo modo, cambierai:

  • il colore delle stelle piene (progressTint)
  • il colore delle stelle non riempite (progressBackgroundTint)
  • e il colore del bordo (secondarioProgressTint) delle stelle

Invece di 3.5 dipinge 4 stelle.
CoolMind

@CoolMind set android: stepSize: 1 anziché 0.5
eLemEnt

4
Come cambiare il colore di una stella vuota?
winklerrr

@winklerrr hai trovato la soluzione su come cambiare il colore di una stella vuota.
Tarun Kumar,

Non ho fatto ulteriori controlli per trovare una soluzione
winklerrr

36

Se vuoi cambiare colore per tutte le stelle ti dice il mio 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);

Esiste un modo per impostare il colore delle stelle in base ai dati recuperati dal database? Diciamo che ho ottenuto 5 stelle e che i dati restituiti dal database erano 4. Quindi, invece di cambiare tutti e 5, cambio solo il primo 4

1
getColor è obsoleto ora, qualche alternativa?
Manohar Reddy,

2
Puoi trovare le risposte qui stackoverflow.com/a/32202256/2513291 Ad esempio questo approccio ContextCompat.getColor (context, R.color.color_name)
Yuriy Vinogradov,

funziona bene, ma nota che, per qualche motivo, l'ordine è importante (2, quindi 1, quindi 0). Ho provato il contrario e ha portato ad alcuni problemi con l'interfaccia utente la prima volta che il colore è cambiato.
Simon Ninon,

25

Le soluzioni che Alex e CommonsWares hanno pubblicato sono corrette. Una cosa di cui Android non parla mai è la dimensione dei pixel corretta per densità diverse. Ecco le dimensioni richieste per ogni densità in base alla luce dell'alone.

Piccola stella

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

Stella media

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

Grande stella

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

posso usare vectordrawble con le stelle
Mina Fawzy il

24

Quindi ho lottato con questo problema per due ore e ho trovato una soluzione funzionante per tutte le versioni di API, in cui vengono mostrate anche le valutazioni a mezza stella.

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

Si chiama il metodo con questo ordine di drawable:

    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: Inoltre, è necessario specificare gli attributi "max" e "numStars" in XML, altrimenti le mezze stelle non vengono visualizzate.


l'unico modo che funziona per me su API19, ma non ho rinunciato a cercare un modo per farlo solo da xml T_T
Beeing Jk

@BeeingJk se si crea una vista personalizzata che estende RatingBar è possibile creare i propri attributi xml per specificare il colore della tinta. Hai quindi un unico punto di controllo per impostare la tinta e puoi specificare la tinta in xml. Spero che aiuti! Può spiegare di più se necessario
Forrest Bice

Mode.SRC_INo Mode.MULTIPLY?
Dr.jacky,

12

Ora puoi utilizzare DrawableCompat da AppCompat v22.1.0 in poi per colorare dinamicamente tutti i tipi di disegni, utile quando supporti più temi con un singolo set di disegni. Per esempio:

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

Questo è retrocompatibile fino all'API 4. Vedi anche il post sul blog di Chris Banes su Support Libraries v22.1.0

Per le dimensioni e la forma effettive, dovrai definire un nuovo stile e disegnabili l'elenco dei livelli per le dimensioni appropriate, come altri hanno già risposto sopra.


I drawable non sono array come stai accedendo a progress [0]?
blueice l'

@blueice Hai ragione scusa, Drawable dovrebbe essere un LayerDrawable, corretto ora, grazie.
Dan Dar3,

Non sembra ancora funzionare per me, ho finito con quello che Yuriy Vinogradov ha fornito una risposta diversa a questa domanda e sembra funzionare.
blueice,

Come cambiare Disegnabile invece Cambia colore?
Iman Marashi,

@ImanMarashi Vedi la risposta basata su XML di Alex sopra, LayerDrawable.setDrawable (indice, disegnabile) è disponibile solo da API23 in poi.
Dan Dar3,

10

Usa android:themeattributo:

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

Per cambiare il colore della barra di valutazione da xml: -

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

non cambia il colore della stella vuota
Nainal

7

Per cambiare il colore non ti resta che impostare il parametro 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"
       />

Per le dimensioni la proprietà dello stile.


funziona solo su API 21 o successiva, grazie
Junaid

5

Il modo più semplice:

android:progressTint="@color/color"

1
Nota che questo funziona solo su api 21+
Ixx

4

Building @ lgvalle's answer.

Aggiornamento 2015

Ora puoi usare DrawableCompat per colorare tutti i tipi di disegni. Per esempio:

Progresso estraibile = ratingBar.getProgressDrawable (); DrawableCompat.setTint (progress, Color.WHITE); Questo è retrocompatibile fino all'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));

Ciò manterrà i colori dei passaggi di frazione.


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

usa il tuo colore


4

Senza aggiungere un nuovo stile puoi usare il colore della tinta all'interno di 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

Funziona per Android sotto e sopra la versione 21

Dopo alcune ricerche ho escogitato questo metodo per impostare la tinta di sfondo, la tinta del gap (es: mezza stella) e il colore della tinta della stella.

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

Soluzione semplice, utilizzare AppCompatRatingBar e il suo metodo setProgressTintList per raggiungere questo obiettivo, vedere questa risposta come riferimento.


Questo ha funzionato per me in API 28 utilizzando com.google.android.material: materiale: 1.1.0-alpha02
Mark Lapasa

2

Risolvo questo problema come segue:

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

Grazie, funziona Ma per la valutazione frazionata le stelle sono interamente dipinte.
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);

per me funziona ....



1

Usando le risposte sopra, ho creato un metodo statico rapido che può essere facilmente riutilizzato. Mira solo a colorare il colore di avanzamento per le stelle attivate. Le stelle che non sono attivate rimangono grigie.

    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 passare la barra di valutazione e un colore utilizzando getResources().getColor(R.color.my_rating_color)

Come puoi vedere, uso DrawableCompat in modo che sia compatibile con le versioni precedenti.

EDIT: questo metodo non funziona su API21 (vai a capire perché). Si finisce con una NullPointerException quando si chiama setProgressBar. Ho finito per disabilitare l'intero metodo su API> = 21.

Per API> = 21, utilizzo la soluzione SupperPuccio.


java.lang.ClassCastException: android.support.v4.graphics.drawable.DrawableWrapperHoneycomb non può essere lanciato su android.graphics.drawable.LayerDrawable su pre-lollipop
Ishaan Garg

1
@IshaanGarg hai ragione. Ho riscontrato lo stesso problema e ho aggiornato il mio metodo. Ho aggiornato il mio codice per gestire il caso. Non penso che sia una questione di versione di Android. Se si utilizza la versione più piccola della barra di classificazione (con style = "? Android: attr / ratingBarStyleSmall"), il disegno restituito rimane comunque LayoutDrawable.
JDenais,

Sì, proprio quello che avevo implementato, assicurati di usare AppCompatRatingBar. Anche se non riesco a ottenere la mezza stella durante la preimpostazione della valutazione da XML / java. Like setRating (3.5) mostra 4 stelle piene
Ishaan Garg il

1

La barra di classificazione viene utilizzata automaticamente in fase di esecuzione per cambiare colore sulla stella a sfioramento.

Per prima cosa aggiungi lo stile nel file app \ src \ main \ res \ valori \ 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>

Quindi la tua barra di valutazione aggiunge un tema come questo:

<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) dichiara questo 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>

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) valutazione attiva --- prendi qualsiasi immagine con colore scuro coz verrà utilizzata come trasparenza del colore per diverse valutazioni

rating_inattivo: scatta qualsiasi immagine delle stesse dimensioni dell'immagine sopra con uno sfondo chiaro .. verrà utilizzata quando non è selezionata alcuna valutazione


0

Un modo molto semplice per cambiare il colore del bordo delle stelle è usare il parametro xml:

android:progressBackgroundTint=""

nella vista ratingBar. Il valore dovrebbe essere un codice esadecimale per un colore.


Non so perché, ma sembra che il metodo influisca solo sul bordo delle stelle (il colore di riempimento rimane il colore predefinito)
superpuccio

Ok, hai perso alcuni parametri XML. Controlla la mia risposta qui sotto.
superpuccio,

1
Hai ragione. Non so perché stavo pensando che avesse problemi a cambiare il colore del bordo della stella (forse perché se il problema avessi). La tua risposta è più completa
Pau Arlandis Martinez,

0

Stavo cercando un metodo affidabile per farlo almeno fino all'API 9. La soluzione "casting to LayerDrawble" mi è sembrata una soluzione rischiosa e quando l'ho testata su un telefono Android su 2.3, è stata lanciata correttamente ma la chiamata a DrawableCompat.setTint (...) non ha avuto alcun effetto.

Nemmeno la necessità di caricare risorse estraibili sembrava una buona soluzione per me.

Ho deciso di codificare la mia soluzione, che è una classe che estende AppCompatRatingBar, usando un Drawable personalizzato che si occupa di disegnare le stelle in modo programmatico. Funziona perfettamente per le mie esigenze, lo posterò nel caso in cui aiuti chiunque:

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

Il collegamento è più semplice perché puoi ottenere direttamente il file completo, ma qui è il codice completo per ogni evenienza:

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

Una risposta un po 'in ritardo, ma spero che possa aiutare alcune persone.

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

Ed ecco come appare WhiteRatingStar

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

Con questo le stelle saranno colorate in bianco per esempio.



-1

Come suggerisce la risposta precedente, non è facile cambiare il colore della barra di valutazione. Le stelle non sono disegnate programmaticamente, sono immagini con dimensioni fisse e gradienti di colore specifici. Per cambiare il colore devi creare le tue stelle con colori diversi, quindi procedi a creare la tua risorsa XML disegnabile e passala alla classe ratingBar usando setProgressDrawable (Drawable d) o l'attributo XML android: progressDrawable.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.