Çubuk yıldız renklerini değiştir [kapalı]


141

Yıldız renklerini ve yıldızların boyutunu nasıl değiştirebilirim?


Bunu yapmak istiyorsanız kendi özel derecelendirme çubuğunuzu oluşturmanız gerektiğini düşünüyorum
Donal Rafferty

RatingBar resimlerini nasıl değiştireceğinizi açıklayan bir blog yazısı yazdım: kozyr.zydako.net/2010/05/23/pretty-ratingbar Ayrıca, resim boyutunu belirleyebileceğiniz yerleri de gösterir ...
kozyr

Bu sorunun web sitelerinde gösterildiği gibi çok renkli derecelendirme çubuğu için olduğunu, kendim için bir tane bulamadığını umuyordum. Kendimi basit bir uygulama github.com/codebreaker/coloredratingbar-android oluşturdu . Umarım bu birisine yardım eder.
jaga

Yanıtlar:


26

Adım # 1: Mevcut stillerden birini (itibaren $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml) klonlayarak , kendi projelerinize koyarak styles.xmlve widget'ı bir mizanpaja eklediğinizde referans vererek kendi stilinizi oluşturun .

2. Adım: Şu kullanıcılar için kendi LayerDrawableXML kaynaklarınızı oluşturun:RatingBar Çubuk için kullanılacak uygun resimlere işaret ederek . Orijinal stiller sizi karşılaştırabileceğiniz mevcut kaynaklara yönlendirecektir. Ardından, kendi stilinizi LayerDrawableyerleşik kaynaklar yerine kendi kaynaklarınızı kullanacak şekilde ayarlayın .


1
2. adıma göre, Bu Samsung 3 cihazları veya diğer bazı cihazlar için çalışmaz, bunun bir LayerDrawable olması gerekmez. Bilgi için buraya bakın: stackoverflow.com/questions/30266334/…
Kenny

6
Android kullanın: progressTint = "@ color / yellow". @Superpuccio'nun cevabına bakınız.
Vincent

2
progressTint sadece 21 api seviyesinin üzerinde destekleniyor
Yogesh Rathi


120

Bahsedilen blogda biraz karmaşık, benzer ama daha basit bir yol kullandım. 3 yıldızlı resimlere (red_star_full.png, red_star_half.png ve red_star_empty.png) ve bir xml'ye ihtiyacınız var, hepsi bu.

Bu 3 görüntüyü res / drawable'a koyun.

Aşağıdaki ratingbar_red.xml'yi buraya koyun:

<?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>

ve son olarak, derecelendirme çubuğu tanımınıza bunu kullanmasını söyleyin, ör.

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

Bu kadar.


3
Merhaba Alex, bu çözümü denedim, ancak derecelendirmeyi 1.1, 1.2, vb. Biri boş, yarısı dolu ve biri dolu olmak üzere 3 yıldız görüntüsü aldım. Kesirli bileşenleri elde etmek için aralarında enterpolasyon yapması gerektiğini düşünüyorum, sadece merak ediyorum başka birisinin aynı sorunu olduğunu mu yoksa belirgin bir şekilde yanlış bir şey mi yapıyorum?
Graham Baitson

Bana hava durumu kullanmalıyız görüntüler hakkında tel lütfen onun renkli görüntüler ve bunu çözmek im im görüntü boyutu ...
Prithviraj Shiroor

1
Herkes 2015 güncelleme cevabını aşağıda görüyor! Çok daha kolay ve basit!
katie

Bu cevap hala yıldızların farklı durumlarına göre daha fazla esneklik sağlar.
Tom Brinkkemper

Neden yıldızların altına dikey çizgiler alıyorum? Özel stil tanımlamayı denedim, yüksekliği belirledim, ancak AVD'imde yıldızların altında hala dikey çizgiler var.
Aleksandar

93

Yalnızca rengi değiştirmek istiyorsanız bunu deneyin:

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

1
Tam olarak ne anlama PorterDuff.Mode.SRC_ATOPgeliyor veya ne anlama geliyor?
Zapnologica

5
API 5.0 ve sonraki sürümlerde çalışmaz. İhtiyaç:Drawable stars = rb.getProgressDrawable(); stars.setTint( Color.YELLOW );
zyamys

@zyamys Bu gerçekten berbat = ("Yüksek sürümler için bir yöntem ve eski sürümler için başka bir yöntem gerekli?"
Daniela Morais

1
Sadece 0,5 hassasiyetle çalışır. Aksi takdirde (hassasiyet <0.5) kaplama garipleşir ve sarı renk
hassasken

1
Uyarı: Lolipop öncesi cihazlarda çökmeler. Kabul edilen cevapla git.
blockwala

70

Benim için en kolay yol ... AppCompat Etkinliğini genişletiyorsanız

Build.gradle dosyasına en son appcompat kütüphanesini ekleyin.

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

Etkinliğinizi android.support.v7.app.AppCompatActivity'yi uzatın

public class MainActivity extends AppCompatActivity {  
    ...
}

Styles.xml dosyanızda özel stil bildirin.

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

Android: theme niteliği ile RatingBar'ınıza bu stili uygulayın.

<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
Teşekkürler @Vishal Kumar. Kitkat 4.4.4 (Samsung S3 neo) ve Marshmallow 6.0.1 (Samsung Galaxy On Nxt) üzerinde denedim, işe yaradı. Ancak Lollipop 5.1'de (Micromax) başarı yok. Lollipop için RatingBar'da "android: progressTint" özniteliğini kullandım ve evet çalışıyor.
Prashant

Bu en iyi çözüm.
Arhat Baid

Bu seçilen doğru cevap olmalıdır.
Hampel Előd

1
Bu en iyi çözümdür. Yıldız boyutunu değiştirmek istiyorsanız, style="?android:ratingBarStyleSmall"birlikte kullanabilirsiniz .
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> ve ratingBar android:theme="@style/RatingBarSmallTheme"
Zakhar Rodionov

47

2015 Güncellemesi

Artık her tür çekmeceyi renklendirmek için DrawableCompat kullanabilirsiniz . Örneğin:

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

Bu, API 4'e kadar geriye dönük olarak uyumludur


Puan çubuğundaki çekilebilir kartı ayarlamayı unutmayın.
15:44

15
Bu, çekilebilir tüm malzemeyi tek bir renge dönüştürür, bu da boş yıldızları ayırt etmeyi çok zorlaştırır.
blueice

Bu sadece android destek kitaplığı> = 22 ile çalışır ve <22 destek kitaplığı ile çalışmaz.
Raghav Sharma

2
3.5 değil, 5 renkli yıldız çizer.
CoolMind

1
Sadece çevreleyen edeceğini ile if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {}bu API 22. varsayılan olarak çalışması nedeniyle şimdilik
Yoann Hercouet

38

API 21'den itibaren, bu üç kod satırı ile yıldızların rengini değiştirmek çok kolay:

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

Böyle yapmak, şunları değiştireceksiniz:

  • doldurulmuş yıldızlar rengi (progressTint)
  • doldurulmamış yıldızlar rengi (progressBackgroundTint)
  • ve yıldızların kenarlık rengi (ikincilProgressTint)

3.5 yerine 4 yıldız boyar.
CoolMind

@CoolMind android ayarla: stepSize: 0.5 yerine 1
eLemEnt

4
Boş bir yıldızın rengi nasıl değiştirilir?
winklerrr

@winklerrr boş bir yıldızın rengini nasıl değiştireceğinizi buldunuz.
Tarun Kumar

Çözüm bulmak için başka kontroller
yapmadı

36

Tüm yıldızların rengini değiştirmek istiyorsanız, kullandığımı belirtir:

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

Veritabanından getirilen verilere göre yıldız rengini ayarlamanın herhangi bir yolu var mı? Diyelim ki 5

1
getColor artık kullanımdan kaldırıldı, başka bir alternatif var mı?
Manohar Reddy

2
Yanıtları burada bulabilirsiniz stackoverflow.com/a/32202256/2513291 Örneğin bu yaklaşım ContextCompat.getColor (içerik, R.color.color_name)
Yuriy Vinogradov

iyi çalışıyor, ancak bir nedenden dolayı siparişin önemli olduğunu unutmayın (2, sonra 1, sonra 0). Tersini denedim ve renk ilk kez değiştiğinde bazı UI aksaklıklarına yol açtı.
Simon Ninon

25

Alex ve CommonsWares'in yayınladığı çözümler doğrudur. Android'in asla bahsetmediği bir şey, farklı yoğunluklar için uygun piksel boyutlarıdır. Halo ışığına dayanan her yoğunluk için gerekli boyutlar.

Küçük Yıldız

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

Orta Yıldız

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

Büyük Yıldız

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

ile vektör çekme özelliğini kullanabilir miyim
Mina Fawzy

24

Bu yüzden iki saat boyunca bu sorunla mücadele ediyorum ve yarım yıldız derecelendirmelerinin de gösterildiği tüm API sürümleri için çalışan bir çözüm buldum.

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

Yöntemi bu sıralanabilir siparişle çağırırsınız:

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

NOT: Ayrıca XML'de "max" ve "numStars" özelliklerini belirtmeniz gerekir, aksi takdirde yarım yıldızlar gösterilmez.


API19'da benim için çalışan tek yol, ancak bunu yalnızca xml'den yapmanın bir yolunu aramayı bırakmadım T_T
Beeing Jk

@BeeingJk RatingBar'ı genişleten özel bir görünüm oluşturursanız, renk tonunu belirtmek için kendi xml özniteliklerinizi oluşturabilirsiniz. Ardından, renk tonunu ayarlamak için tek bir denetim noktanız vardır ve renk tonunu xml olarak belirtebilirsiniz. Umarım yardımcı olur! Gerekirse daha fazla açıklayabilir
Forrest Bice

Mode.SRC_INveya Mode.MULTIPLY?
Dr.jacky

12

Artık AppCompat v22.1.0'dan itibaren DrawableCompat'ı , her türlü çekmeceyi dinamik olarak renklendirmek için kullanabilirsiniz , tek bir çekilebilir setle birden fazla temayı desteklerken faydalıdır. Örneğin:

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

Bu, API 4 ile geriye dönük olarak uyumludur. Ayrıca Chris Banes'in Destek Kitaplıkları v22.1.0 hakkındaki blog yayınına bakın

Gerçek boyut ve şekil için, diğerlerinin yukarıda yanıtladığı gibi, uygun boyut için yeni bir stil ve katman listesi çekilebilirleri tanımlamanız gerekecektir.


Çekmeceler diziler değil [0] ilerlemesine nasıl erişiyorsunuz?
blueice

@blueice Doğru özür dileriz, Drawable bir LayerDrawable olmalı, şimdi düzeltildi, teşekkürler.
Dan Dar3

Benim için hala işe yaramadı, Yuriy Vinogradov'un bu soruya farklı bir yanıt verdiğini ve sonuçta işe yaradığını gördüm.
blueice

Çizilebilir nasıl değiştirilir Renk değiştirilir?
Iman Marashi

@ImanMarashi Alex'in yukarıdaki XML tabanlı cevabına bakın, LayerDrawable.setDrawable (dizin, çekilebilir) yalnızca API23'ten itibaren kullanılabilir.
Dan Dar3

10

kullanım android:themeÖzellik :

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

Sadece Rating çubuğunun rengini xml'den değiştirmek için: -

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

boş yıldız rengini değiştirmez
Nainal

7

Rengi değiştirmek için sadece android parametresini ayarlamanız gerekir: 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"
       />

Boyut için style özelliği.


yalnızca API 21 veya daha üstü sürümlerde çalışır, teşekkürler
Junaid

5

En basit yol:

android:progressTint="@color/color"

1
Bunun yalnızca API 21+ üzerinde çalıştığını unutmayın
Ixx

4

Building @ lgvalle cevabı.

2015 Güncellemesi

Artık her tür çekmeceyi renklendirmek için DrawableCompat kullanabilirsiniz. Örneğin:

Çekilebilir ilerleme = ratingBar.getProgressDrawable (); DrawableCompat.setTint (ilerleme durumu, Color.WHITE); Bu, API 4'e kadar geriye dönük olarak uyumludur

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

Bu, kesir adımları renklerini koruyacaktır.


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

kendi rengini kullan


4

Yeni bir stil ekleyerek içindeki renk tonunu kullanabilirsiniz. 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

Sürüm 21'in altında ve üstünde Android için çalışır

Bazı araştırmalardan sonra, arka plan tonunu, boşluk tonunu (örn: yarım yıldız) ve yıldız tonu rengini ayarlamak için bu yöntemi geliştirdim.

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

Basit bir çözüm, kullanım AppCompatRatingBar ve setProgressTintList bunu başarmak için yöntem, bu bakınız cevabı referans için.


Bu benim için com.google.android.material: material: 1.1.0-alpha02
Mark Lapasa

2

Bu sorunu şu şekilde çözdüm:

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

Teşekkürler, işe yarıyor. Ancak kesirli derecelendirme için yıldızlar tamamen boyanır.
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);

benim için çalışıyor ....



1

Yukarıdaki cevapları kullanarak, kolayca tekrar kullanılabilecek hızlı bir statik yöntem oluşturdum. Sadece aktive edilen yıldızlar için ilerleme rengini renklendirmeyi amaçlamaktadır. Etkinleştirilmeyen yıldızlar gri kalır.

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

Sadece derecelendirme çubuğunuzu ve bir Renk kullanarak getResources().getColor(R.color.my_rating_color)

Gördüğünüz gibi, DrawableCompat kullanıyorum, böylece geriye dönük uyumlu.

EDIT: Bu yöntem API21 üzerinde çalışmaz (neden şekil). SetProgressBar öğesini çağırırken NullPointerException ile sonuçlanırsınız. API> = 21 üzerindeki tüm yöntemi devre dışı bıraktım.

API> = 21 için SupperPuccio çözümü kullanıyorum.


java.lang.ClassCastException: android.support.v4.graphics.drawable.DrawableWrapperHoneycomb, lolipop öncesi android.graphics.drawable.LayerDrawable
Ishaan Garg

1
@IshaanGarg haklısın. Aynı sorunla karşılaştım ve yöntemimi güncelledim. Davayı işlemek için kodumu güncelledim. Android sürümü meselesi olduğunu sanmıyorum. Derecelendirme çubuğunun daha küçük sürümünü (style = "? Android: attr / ratingBarStyleSmall" ile) kullanıyorsanız, döndürülen çekilebilir öğe yine de bir LayoutDrawable olur.
JDenais

Evet, tam olarak uyguladığım şey, sadece AppCompatRatingBar kullandığınızdan emin olun. XML / java için derecelendirmeyi önceden ayarlarken yarım yıldız alamıyorum. Like setRating (3.5) 4 tam yıldız gösterir
Ishaan Garg

1

Derecelendirme çubuğu, dokunmatik yıldızda renk değiştirmek için çalışma zamanında otomatik olarak kullanılır.

Önce app \ src \ main \ res \ değerleri \ styles.xml dosyasına stil ekleyin:

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

Daha sonra derecelendirme çubuğunuz böyle bir tema ekler:

<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) Bu XML'i beyan et

<LinearLayout 
             android:layout_width="match_parent"
        android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:orientation="horizontal"
         android:paddingLeft="20dp"
         android:paddingRight="20dp"
         android:layout_marginBottom="20dp"
         android:background="#323232"
         android:gravity="center_horizontal">

       <com.example.android.custom_ratingbar.CustomRatingBar
        android:id="@+id/coloredRatingBar5"
        style="@style/coloredRatingBarStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"

         />
       </LinearLayout>

2) style.xml içinde

<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) derecelendirme aktif --- koyu renk coz ile herhangi bir görüntü çekin farklı derecelendirme için renk şeffaflığı olarak kullanılacak

rating_inactive - açık renkli arka plan üzerinde yukarıdaki boyuttaki herhangi bir resmi çeker ... hiçbir derecelendirme seçilmediğinde kullanılır


0

Yıldızların kenarlık rengini değiştirmenin çok kolay bir yolu xml parametresini kullanmaktır:

android:progressBackgroundTint=""

Çubuk görünümünde. Değer, bir renk için onaltılık bir kod olmalıdır.


Nedenini bilmiyorum, ancak yöntem sadece yıldızların kenarlığını etkiliyor gibi görünüyor (dolgu rengi varsayılan renk olarak kalır)
superpuccio

Tamam, bazı xml parametrelerini kaçırdınız. Cevabımı aşağıda bulabilirsiniz.
superpuccio

1
Haklısın. Neden yıldızın kenarlık rengini değiştirmekte sorun yaşadığını düşündüğümü bilmiyorum (belki sorunum varsa). Cevabınız daha eksiksiz.
Pau Arlandis Martinez

0

En azından API 9'a kadar bunu yapmak için güvenilir bir yöntem arıyordum. "LayerDrawble'a döküm" çözümü benim için riskli bir çözüm gibi görünüyordu ve 2.3'te bir Android telefonda test ettiğimde başarılı bir şekilde yayınlandı, ancak DrawableCompat.setTint (...) çağrısının herhangi bir etkisi olmadı.

Çekilebilir varlık yükleme ihtiyacı da benim için iyi bir çözüm gibi görünmüyordu.

Yıldızları programlı olarak çizmeye özen gösteren özel bir Drawable kullanarak AppCompatRatingBar'ı genişleten bir sınıf olan kendi çözümümü kodlamaya karar verdim. İhtiyaçlarım için mükemmel çalışıyor, herkese yardımcı olması durumunda göndereceğim:

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

Bağlantı daha kolaydır, çünkü tam dosyayı doğrudan alabilirsiniz, ancak tam kod aşağıdadır:

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

Biraz geç cevap ama umarım bazı millet yardımcı olacaktır.

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

İşte WhiteRatingStar'ın görünüşü

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

Bununla yıldızlar örneğin beyaza boyanacak.



-1

Önceki yanıtın da gösterdiği gibi, derecelendirme çubuğunun rengini değiştirmek kolay değildir. Yıldızlar programlı olarak çizilmez, sabit boyutlu ve belirli renk gradyanlarına sahip görüntülerdir. Rengi değiştirmek için farklı renklerle kendi yıldız görüntülerinizi oluşturmanız gerekir, ardından kendi çekilebilir XML kaynağınızı oluşturmaya devam edin ve setProgressDrawable (Drawable d) veya XML niteliği android: progressDrawable kullanarak derecelendirmeBar sınıfına iletin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.