Android RatingBar Sternfarben ändern [geschlossen]

141

Wie kann ich die Sternfarben und die Größe der Sterne ändern?

D-Mann
quelle
Ich denke, Sie müssen Ihre eigene benutzerdefinierte Bewertungsleiste erstellen, wenn Sie das tun möchten
Donal Rafferty
Ich habe einen Blog-Beitrag geschrieben, in dem beschrieben wird, wie RatingBar-Bilder geändert werden: kozyr.zydako.net/2010/05/23/pretty-ratingbar Außerdem wird angezeigt , wo Sie die Bildgröße angeben können ...
kozyr
Ich hatte gehofft, diese Frage ist für mehrfarbige Bewertungsbalken, wie auf Websites gezeigt, konnte keine für mich finden. Ich habe selbst eine einfache Implementierung erstellt: github.com/codebreaker/coloredratingbar-android . Hoffe das hilft jemandem da draußen.
Jaga

Antworten:

26

Schritt 1: Erstellen Sie Ihren eigenen Stil, indem Sie einen der vorhandenen Stile (von $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml) klonen , ihn in Ihr eigenes Projekt einfügen styles.xmlund ihn referenzieren, wenn Sie das Widget einem Layout hinzufügen.

Schritt 2: Erstellen Sie Ihre eigenen LayerDrawableXML-Ressourcen für die RatingBarund zeigen Sie auf die entsprechenden Bilder, die für die Leiste verwendet werden sollen. Die ursprünglichen Stile verweisen auf die vorhandenen Ressourcen, mit denen Sie vergleichen können. Passen Sie dann Ihren Stil an, um Ihre eigenen LayerDrawableRessourcen anstelle der integrierten zu verwenden.

CommonsWare
quelle
1
Gemäß Schritt 2 funktioniert dies nicht für Samsung 3-Geräte oder andere Geräte. Dies muss kein LayerDrawable sein. Siehe hier für Informationen: stackoverflow.com/questions/30266334/…
Kenny
6
Verwenden Sie Android: progressTint = "@ Farbe / Gelb". Siehe die Antwort von @superpuccio.
Vincent
2
progressTint wird nur über 21 api unterstützt
Yogesh Rathi
Dies ist die beste Lösung: stackoverflow.com/a/36297738/1935135
André Luiz Reis
120

Bei dem erwähnten Blog ist es etwas kompliziert, ich habe einen ähnlichen, aber einfacheren Weg gewählt. Sie benötigen 3-Sterne-Bilder (red_star_full.png, red_star_half.png und red_star_empty.png) und eine XML, das ist alles.

Setzen Sie diese 3 Bilder auf res / drawable.

Geben Sie dort die folgende Bewertung ein: barbar_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>

und schließlich teilen Sie Ihrer Bewertungsbalkendefinition mit, dies zu verwenden, d. h

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

Das ist es.

Alex
quelle
3
Hallo Alex, ich habe diese Lösung ausprobiert, aber wenn ich versuche, die Bewertung auf 1,1, 1,2 usw. einzustellen, wird sie als 1,5 angezeigt. Ich habe 3-Sterne-Bilder aufgenommen, eines leer, eines halb voll und eines voll. Ich nehme an, es soll zwischen ihnen interpolieren, um die Bruchkomponenten zu erhalten. Ich frage mich nur, ob jemand das gleiche Problem hatte oder mache ich etwas merklich Falsches?
Graham Baitson
Können Sie mich bitte über die Bilder anrufen, die wir verwenden sollten
? Es sind
1
Jeder sieht die Antwort auf das Update 2015 unten! Es ist viel einfacher und einfacher!
Katie
Diese Antwort bietet noch mehr Flexibilität über die verschiedenen Zustände der Sterne.
Tom Brinkkemper
Warum bekomme ich vertikale Linien unter Sternen? Ich habe versucht, einen benutzerdefinierten Stil zu definieren und die Höhe anzugeben, aber auf meiner AVD befinden sich immer noch vertikale Linien unter den Sternen.
Aleksandar
93

Versuchen Sie dies, wenn Sie nur die Farbe ändern möchten:

RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
Mirek Michalak
quelle
1
Was genau PorterDuff.Mode.SRC_ATOPbedeutet oder tut?
Zapnologica
5
Funktioniert nicht mit API 5.0 und höher. Bedürfnisse:Drawable stars = rb.getProgressDrawable(); stars.setTint( Color.YELLOW );
Zyamys
@zyamys Das ist wirklich scheiße = (Eine Methode für "höhere Versionen" und eine andere Methode für ältere Versionen ist notwendig?
Daniela Morais
1
Es funktioniert nur mit einer Genauigkeit von 0,5. Andernfalls (Genauigkeit <0,5) wird die Überlagerung seltsam und scheint, dass die blaue Farbe immer noch eine Genauigkeit von 0,5 hat, während die gelbe genau ist
Teo Inke
1
Warnung: Abstürze auf Pre-Lolipop-Geräten. Gehen Sie mit der akzeptierten Antwort.
Blockwala
70

Der einfachste Weg, der für mich funktioniert hat ... wenn Sie die AppCompat-Aktivität erweitern

Fügen Sie in Ihrem build.gradle die neueste Appcompat-Bibliothek hinzu.

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

Erweitern Sie Ihre Aktivität android.support.v7.app.AppCompatActivity

public class MainActivity extends AppCompatActivity {  
    ...
}

Deklarieren Sie einen benutzerdefinierten Stil in Ihrer Datei styles.xml.

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

Wenden Sie diesen Stil über das Attribut android: theme auf Ihre RatingBar an.

<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"/>
Vishal Kumar
quelle
3
Vielen Dank an Vishal Kumar. Ich habe es mit Kitkat 4.4.4 (Samsung S3 neo) und Marshmallow 6.0.1 (Samsung Galaxy On Nxt) versucht, es hat funktioniert. Aber kein Erfolg auf Lollipop 5.1 (Micromax). Für Lollipop habe ich das Attribut "android: progressTint" in RatingBar verwendet und ja, es funktioniert.
Prashant
Das ist die beste Lösung.
Arhat Baid
Dies sollte die ausgewählte richtige Antwort sein.
Hampel Előd
1
Dies ist die beste Lösung. Wenn Sie die Sterngröße ändern möchten, können Sie sie style="?android:ratingBarStyleSmall"zusammen verwenden.
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> und Ihre BewertungBar android:theme="@style/RatingBarSmallTheme"
Zakhar Rodionov
47

Update 2015

Jetzt können Sie DrawableCompat verwenden, um alle Arten von Drawables zu tönen. Beispielsweise:

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

Dies ist abwärtskompatibel bis API 4

lgvalle
quelle
Vergessen Sie nicht, das Drawable wieder auf die Ratingleiste zu setzen.
Squeeish
15
Dies färbt das gesamte Zeichenbare in eine Farbe, wodurch die leeren Sterne sehr schwer zu unterscheiden sind.
Blueice
Dies funktioniert nur mit der Android-Unterstützungsbibliothek> = 22 und nicht mit der Unterstützungsbibliothek <22.
Raghav Sharma
2
Es zeichnet 5 farbige Sterne, nicht 3,5.
CoolMind
1
Ich würde das nur umgeben, if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {}da es standardmäßig von API 22 aus funktioniert.
Yoann Hercouet
37

Ab der API 21 ist es sehr einfach, die Farbe der Sterne mit diesen drei Codezeilen zu ändern:

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

Wenn Sie es so machen, werden Sie Folgendes ändern:

  • die Farbe der gefüllten Sterne (progressTint)
  • die Farbe der ungefüllten Sterne (progressBackgroundTint)
  • und die Rahmenfarbe (SecondaryProgressTint) der Sterne
Superpuccio
quelle
Anstelle von 3,5 werden 4 Sterne gemalt.
CoolMind
@CoolMind set android: stepSize: 1 statt 0.5
eLemEnt
4
Wie ändere ich die Farbe eines leeren Sterns?
Winklerrr
@winklerrr hast du eine Lösung gefunden, wie du die Farbe eines leeren Sterns ändern kannst?
Tarun Kumar
Ich
36

Wenn Sie die Farbe für alle Sterne ändern möchten, geben Sie meine Verwendung an:

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);
Yuriy Vinogradov
quelle
Gibt es Möglichkeiten, die Farbe der Sterne basierend auf den aus der Datenbank abgerufenen Daten festzulegen? Angenommen, ich habe 5 Sterne erhalten und die von der Datenbank zurückgegebenen Daten waren 4. Anstatt alle 5 zu ändern, ändere ich nur die ersten 4
1
getColor ist jetzt veraltet, eine Alternative?
Manohar Reddy
2
Antworten finden Sie hier stackoverflow.com/a/32202256/2513291 Zum Beispiel dieser Ansatz ContextCompat.getColor (Kontext, R.color.color_name)
Yuriy Vinogradov
funktioniert gut, aber beachten Sie, dass aus irgendeinem Grund die Reihenfolge wichtig ist (2, dann 1, dann 0). Ich habe das Gegenteil versucht und es führte zu einigen UI-Störungen, wenn die Farbe zum ersten Mal geändert wurde.
Simon Ninon
25

Die von Alex und CommonsWares veröffentlichten Lösungen sind korrekt. Eine Sache, über die Android nie spricht, sind die richtigen Pixelgrößen für unterschiedliche Dichten. Hier sind die erforderlichen Abmessungen für jede Dichte basierend auf Halo-Licht.

Kleiner Stern

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

Mittlerer Stern

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

Großer Stern

mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
Dirkoneill
quelle
Kann ich Vectordrawble mit Sternen verwenden
Mina Fawzy
24

Daher habe ich zwei Stunden lang mit diesem Problem zu kämpfen und eine funktionierende Lösung für alle API-Versionen gefunden, bei der auch Bewertungen mit halben Sternen angezeigt werden.

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

Sie rufen die Methode mit dieser Reihenfolge von Zeichen auf:

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

HINWEIS: Außerdem müssen Sie die Attribute "max" und "numStars" in XML angeben, da sonst keine halben Sterne angezeigt werden.

Box
quelle
Der einzige Weg, der für mich auf API19 funktioniert, aber ich habe es nicht aufgegeben, nach einem Weg zu suchen, dies nur von XML aus zu tun. T_T
Beeing Jk
@BeeingJk Wenn Sie eine benutzerdefinierte Ansicht erstellen, die RatingBar erweitert, können Sie Ihre eigenen XML-Attribute erstellen, um die Farbtonfarbe anzugeben. Sie haben dann einen einzigen Kontrollpunkt zum Festlegen des Farbtons und können den Farbton in XML angeben. Hoffentlich hilft das! Kann bei Bedarf mehr erklären
Forrest Bice
Mode.SRC_INoder Mode.MULTIPLY?
Dr. Jacky
12

Jetzt können Sie DrawableCompat ab AppCompat v22.1.0 verwenden, um alle Arten von Drawables dynamisch zu tönen. Dies ist nützlich, wenn Sie mehrere Themen mit einem einzigen Satz von Drawables unterstützen. Beispielsweise:

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

Dies ist bis auf API 4 abwärtskompatibel. Siehe auch den Blog-Beitrag von Chris Banes zu Support Libraries v22.1.0

Für die tatsächliche Größe und Form müssen Sie einen neuen Stil und eine neue Ebenenliste für die entsprechende Größe definieren, wie andere bereits oben geantwortet haben.

Dan Dar3
quelle
Drawables sind keine Arrays. Wie greifen Sie auf Fortschritt zu? [0]?
Blueice
@blueice Es tut dir leid, Drawable sollte ein LayerDrawable sein, jetzt korrigiert, danke.
Dan Dar3
Es schien immer noch nicht für mich zu funktionieren, ich endete damit, dass Yuriy Vinogradov eine andere Antwort auf diese Frage gab, und das scheint zu funktionieren.
Blueice
Wie ändere ich stattdessen Drawable? Ändere die Farbe?
Iman Marashi
@ImanMarashi Siehe Alex 'XML-basierte Antwort oben. LayerDrawable.setDrawable (Index, Drawable) ist nur ab API23 verfügbar.
Dan Dar3
10

Verwenden Sie android:themeAttribut:

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" />
Hidro
quelle
9

Zum einfachen Ändern der Farbe der Bewertungsleiste von XML: -

android:progressTint="@color/your_color"
android:backgroundTint="@color/your_color"
android:secondaryProgressTint="@color/your_color"
Rahul
quelle
es ändert nicht leere
Sternfarbe
7

Um die Farbe zu ändern, müssen Sie nur den Parameter android: progressTint setzen

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

Für die Größe die Stileigenschaft.

letrounet
quelle
funktioniert nur auf API 21 oder höher, danke
Junaid
5

Der einfachste Weg:

android:progressTint="@color/color"
Mehatab
quelle
1
Beachten Sie, dass dies nur auf API 21+
Ixx
4

Die Antwort von Building @ lgvalle.

Update 2015

Jetzt können Sie DrawableCompat verwenden, um alle Arten von Drawables zu tönen. Beispielsweise:

Drawable progress = RatingBar.getProgressDrawable (); DrawableCompat.setTint (Fortschritt, Color.WHITE); Dies ist abwärtskompatibel bis 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));

Dadurch bleiben die Farben der Bruchschritte erhalten.

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

benutze deine eigene Farbe

Sibasisch
quelle
4

Ohne einen neuen Stil hinzuzufügen, können Sie die Farbtonfarbe innerhalb der verwenden 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"/>
4ndro1d
quelle
3

Funktioniert für Android unter und über Version 21

Nach einigen Recherchen habe ich mir diese Methode ausgedacht, um die Hintergrundfarbe, die Spalttönung (z. B. halber Stern) und die Sternfarbe festzulegen.

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
Arbitur
quelle
3

Verwenden Sie AppCompatRatingBar und die setProgressTintList- Methode, um dies zu erreichen . Eine Referenz finden Sie in dieser Antwort .

Kuldeep Sakhiya
quelle
Dies funktionierte für mich unter API 28 mit com.google.android.material: material: 1.1.0-alpha02
Mark Lapasa
2

Ich löse dieses Problem wie folgt:

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);
Hai Rom
quelle
Danke, es funktioniert. Aber für Teilbewertungen werden Sterne vollständig gemalt.
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);

für mich funktioniert es ....

Vimesh Pk
quelle
1

Ich habe eine einfache Lösung gefunden, um die Farbe des Sterns entsprechend Ihrem Thema zu ändern.

Gehe zu dieser Seite: http://android-holo-colors.com/

Wählen Sie Ihre Themenfarbe und lassen Sie Ihre Sternbilder erstellen.

Hardik4560
quelle
1

Mit den obigen Antworten habe ich eine schnelle statische Methode erstellt, die leicht wiederverwendet werden kann. Es zielt nur darauf ab, die Fortschrittsfarbe für die aktivierten Sterne zu tönen. Die nicht aktivierten Sterne bleiben grau.

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

Übergeben Sie einfach Ihre Bewertungsleiste und eine Farbe mit getResources().getColor(R.color.my_rating_color)

Wie Sie sehen können, verwende ich DrawableCompat, damit es abwärtskompatibel ist.

BEARBEITEN: Diese Methode funktioniert nicht mit API21 (siehe Abbildung warum). Sie erhalten eine NullPointerException, wenn Sie setProgressBar aufrufen. Am Ende habe ich die gesamte Methode auf API> = 21 deaktiviert.

Für API> = 21 verwende ich die SupperPuccio-Lösung.

JDenais
quelle
java.lang.ClassCastException: android.support.v4.graphics.drawable.DrawableWrapperHoneycomb kann nicht in android.graphics.drawable.LayerDrawable auf Pre-Lollipop umgewandelt werden
Ishaan Garg
1
@IshaanGarg du hast recht. Ich bin auf dasselbe Problem gestoßen und habe meine Methode aktualisiert. Ich habe meinen Code aktualisiert, um den Fall zu behandeln. Ich denke nicht, dass es sich um eine Android-Version handelt. Wenn Sie die kleinere Version der Bewertungsleiste verwenden (mit style = "? Android: attr / gradeBarStyleSmall"), ist das zurückgegebene Zeichen weiterhin ein LayoutDrawable.
JDenais
Ja, genau das, was ich implementiert hatte, verwenden Sie unbedingt AppCompatRatingBar. Obwohl ich keinen halben Stern bekommen kann, wenn ich die Bewertung von XML / Java voreinstelle. Wie setRating (3.5) zeigt 4 volle Sterne
Ishaan Garg
1

Die Bewertungsleiste wird zur Laufzeit automatisch zum Ändern der Farbe auf dem Touch Star verwendet.

Fügen Sie zuerst den Stil in der Datei app \ src \ main \ res \ values ​​\ styles.xml hinzu:

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

Dann fügt Ihre Bewertungsleiste ein Thema wie das folgende hinzu:

<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"/>
Navadip Patel
quelle
0

1) deklarieren Sie diese 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) Bewertung aktiv --- Nehmen Sie ein Bild mit dunkler Farbe auf, da es als Farbtransparenz für unterschiedliche Bewertungen verwendet wird

review_inactive - Nimm ein Bild mit der gleichen Größe wie das obige Bild mit hellem Hintergrund auf. Es wird verwendet, wenn keine Bewertung ausgewählt ist

amit
quelle
0

Eine sehr einfache Möglichkeit, die Rahmenfarbe der Sterne zu ändern, ist die Verwendung des XML-Parameters:

android:progressBackgroundTint=""

in der RatingBar-Ansicht. Der Wert sollte ein hexadezimaler Code für eine Farbe sein.

Pau Arlandis Martinez
quelle
Ich weiß nicht warum, aber es scheint, dass
Ihre
Ok, du hast einige XML-Parameter verpasst. Schauen Sie sich meine Antwort hier unten an.
Superpuccio
1
Du hast recht. Ich weiß nicht, warum ich dachte, er hätte Probleme, die Randfarbe des Sterns zu ändern (vielleicht, weil ich das Problem hatte). Ihre Antwort ist vollständiger.
Pau Arlandis Martinez
0

Ich suchte nach einer zuverlässigen Methode, um dies zumindest bis hin zu API 9 zu tun. Die "Casting to LayerDrawble" -Lösung schien mir eine riskante Lösung zu sein, und als ich sie auf einem Android-Telefon unter 2.3 ausprobierte, wurde sie erfolgreich gewirkt, aber der Aufruf von DrawableCompat.setTint (...) hatte keine Auswirkungen.

Die Notwendigkeit, zeichnbare Vermögenswerte zu laden, schien mir auch keine gute Lösung zu sein.

Ich habe mich entschlossen, meine eigene Lösung zu codieren, bei der es sich um eine Klasse handelt, die AppCompatRatingBar erweitert. Dabei wurde ein benutzerdefiniertes Drawable verwendet, mit dem die Sterne programmgesteuert gezeichnet werden. Es funktioniert perfekt für meine Bedürfnisse, ich werde es posten, falls es jemandem hilft:

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

Der Link ist einfacher, da Sie die vollständige Datei direkt abrufen können. Hier ist jedoch der vollständige Code für alle Fälle:

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;
        }
    }
}
androidseb
quelle
0

Eine etwas späte Antwort, aber ich hoffe, es wird einigen Leuten helfen.

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

Und so sieht der WhiteRatingStar aus

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

Damit werden die Sterne zum Beispiel weiß gefärbt.

Martial Konvi
quelle
-1

Wie die vorherige Antwort impliziert, ist es nicht einfach, die Farbe der Bewertungsleiste zu ändern. Die Sterne werden nicht programmgesteuert gezeichnet, sondern sind Bilder mit fester Größe und spezifischen Farbverläufen. Um die Farbe zu ändern, müssen Sie Ihre eigenen Sternbilder mit verschiedenen Farben erstellen. Erstellen Sie dann Ihre eigene zeichnbare XML-Ressource und übergeben Sie sie mit setProgressDrawable (Drawable d) oder dem XML-Attribut android: progressDrawable an die reviewsBar-Klasse.

David
quelle