Android RatingBar: не может заполнить частичный рейтингBar, если я настрою его цвет

Я установил цвет ratingBar на другой цвет для Android по умолчанию - синий и серый - я выбрал свои звезды с черным фоном и розовыми, если они выбраны.

Это мой код для моей mainactivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingbar);
        LayerDrawable layerDrawable2 = (LayerDrawable) ratingBar.getProgressDrawable();
        DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0)),
                ContextCompat.getColor(getApplicationContext(), android.R.color.background_dark));
        DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1)),
                ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); // Partial star
        DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2)),
                ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));
        ratingBar.setIsIndicator(false);
        ratingBar.setRating(3.6f);
        ratingBar.setStepSize(0.1f);
        ratingBar.invalidate();
        ratingBar.setIsIndicator(true);
    }
}

Вы можете видеть, что если я ставлю рейтинг 3,6, он выбирает до 4.

введите описание изображения здесь

Однако, если я прокомментирую свои собственные настроенные цвета, ratingBar правильно настроит отображение только части 4-й звезды, заполненной, так как переданное ей значение равно 3.6:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingbar);
/*        LayerDrawable layerDrawable2 = (LayerDrawable) ratingBar.getProgressDrawable();
        DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0)),
                ContextCompat.getColor(getApplicationContext(), android.R.color.background_dark));
        DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1)),
                ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); // Partial star
        DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2)),
                ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));*/
        ratingBar.setIsIndicator(false);
        ratingBar.setRating(3.6f);
        ratingBar.setStepSize(0.1f);
        ratingBar.invalidate();
        ratingBar.setIsIndicator(true);
    }
}

введите описание изображения здесь

Почему это, если я создаю свои собственные пользовательские цвета, ratingBar не заполняется должным образом?

Я создал небольшое репо, и вы можете скачать его и протестировать здесь: https://github.com/Winghin2517/RatingBarTest2

EDIT:

Библиотека FlyingPumba демонстрирует некоторые надежды на то, что я хочу достичь, но мне нужен стиль, когда фон звезд белый, когда он появляется на экране, и он будет заполнен сплошным цветом, когда пользователи нажимают на звезду. В моем случае я хочу, чтобы он был заполнен зеленым цветом.

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

Также мне не нужен белый штрих для звезд вообще, поскольку я хочу, чтобы стиль стилей был простым.

<com.iarcuschin.simpleratingbar.SimpleRatingBar
    android:id="@+id/ratingBar3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    app:srb_rating="3.6"
    app:srb_fillColor="@color/material_greenA700"
    app:srb_borderColor="@color/material_white"
    app:srb_starBorderWidth="0"
    app:srb_pressedFillColor="@color/material_greenA700"
    app:srb_starSize="30dp"
    />

введите описание изображения здесь

Ответ 1

Вы на правильном пути с тем, что вы пытаетесь. Единственное, что вы сделали неправильно, - это присвоить неправильный цвет второму доступному.

Подумайте о том, что второй можно использовать в качестве фона звезды, а не на переднем плане. Поэтому частичным звездам нужен цвет фона, а не цвет звезд, т.е. В вашем примере, черный, а не розовый.

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

    RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingbar);
    LayerDrawable layerDrawable2 = (LayerDrawable) ratingBar.getProgressDrawable();

    // No star
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0)),
            ContextCompat.getColor(getApplicationContext(),
                    android.R.color.background_dark));

    // Partial star 
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1)),
            ContextCompat.getColor(getApplicationContext(),
                    // use background_dark instead of colorAccent
                    // R.color.colorAccent));
                    android.R.color.background_dark));

    // Custom star
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2)),
            ContextCompat.getColor(getApplicationContext(),
                    R.color.colorAccent));

Другой способ сделать это и, возможно, лучше во многих случаях - использовать правильный стиль в RatingBar.

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

Я не буду вдаваться в подробности, потому что фактический xml-код показан в ответе Anantham.

Ответ 2

в Activity.java:

oncreate:

       RatingBar   setRatingBar = (RatingBar) findViewById(R.id.setRating);
       float rating = Float.parseFloat(listString);
      // onRatingChanged(setRatingBar, 0.0f, true);

        public void onRatingChanged(RatingBar rateBar, float rating, boolean fromUser) {
    try {
        DecimalFormat decimalFormat = new DecimalFormat("#.#");
        curRate = Float.valueOf(decimalFormat.format((curRate * count + rating)/ ++count));
        float userRatePoint = curRate/**20*/;

        setRatingBar.setRating(userRatePoint);
        countText = (TextView) findViewById(R.id.countText);
        countText.setText(userRatePoint + " Ratings");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

затем попробуйте это для малой шкалы рейтинга:

    <RatingBar
     android:id="@+id/setRating"
     style="?android:attr/ratingBarStyleSmall"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_marginLeft="10dp"
     android:layout_marginTop="3dp"
     android:isIndicator="true"
     android:numStars="5"
     android:stepSize="0.1" />
       //if you want to style please use "foodRatingBar"
       //for custom star image use  "ratingstar"

style.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="foodRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/ratingstar</item>
    <item name="android:minHeight">22dip</item>
    <item name="android:maxHeight">22dip</item>
</style>

значения v11/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="foodRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/ratingstar</item>
    <item name="android:minHeight">22dip</item>
    <item name="android:maxHeight">22dip</item>
</style>

значения v14/styles.xml

 <resources>
   <style name="foodRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/ratingstar</item>
    <item name="android:minHeight">22dip</item>
    <item name="android:maxHeight">22dip</item>
</style>
<!--
    Base application theme for API 14+. This theme completely replaces
    AppBaseTheme from BOTH res/values/styles.xml and
    res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <!-- API 14 theme customizations can go here. -->
</style>
</resources>

ratingstar.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/ratingstar_default" />
        <item android:id="@android:id/secondaryProgress"
            android:drawable="@drawable/ratingstar_default" />
        <item android:id="@android:id/progress"
            android:drawable="@drawable/ratingstar_selected" />
    </layer-list>
</resources>

Ответ 3

Вам просто нужно обновить DrawableCompat.wrap(..) drawable с помощью .mutate(). код выглядит следующим образом:

DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(0).mutate()),
            ContextCompat.getColor(getApplicationContext(), android.R.color.background_dark));
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(1).mutate()),
            ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); // Partial star
    DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable2.getDrawable(2).mutate()),
            ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));

Если цвет изменяется динамически, то он должен быть изменчивым

Смотрите вопрос: Android: оттенок с использованием DrawableCompat

и ответьте: fooobar.com/questions/119964/...

Вы можете посмотреть Рисованные мутации блога Ромен Гая, а также посмотреть mutate() метод разработчика разработчика android.

Я надеюсь, что это поможет вам.

Ответ 4

Использование фондового рейтинга Bar может быть очень болезненным, вы должны попробовать эту библиотеку: SimpleRatingBar.

(Я немного предвзятый, поскольку я создатель)

В нем есть:

  • Полностью работает android:layout_width: его можно установить в wrap_content, match_parent или abritary dp.
  • Произвольное число звезд.
  • Произвольный размер шага.
  • Размер звезд можно точно контролировать или установить максимальный размер.
  • Настраиваемые цвета в нормальном состоянии (граница, заливка и фон звезд).
  • Настраиваемые цвета в нажатом состоянии (граница, заливка и фон звезд).
  • Настраиваемая разметка размеров между звездами.
  • Настраиваемая ширина границ звезд.
  • Настраиваемый радиус угла звезд.
  • Позволяет установить OnRatingBarChangeListener
  • Заполнение звездочек может начинаться слева направо или справа налево (поддержка языка RTL).
  • AnimationBuilder интегрирован в представление, чтобы автоматически присвоить рейтинг анимации.

Это предварительный просмотр.

Вы можете найти его либо в jcenter, либо в Maven Central. Поэтому в вашем файле build.gradle просто добавьте в свои зависимости:

compile 'com.iarcuschin:simpleratingbar:0.1.+'

EDIT: Недавно я добавил возможность изменения цвета фона звезд (пустой цвет) и отключения границы. Чтобы достичь желаемого, вы можете добавить к своему макету:

<com.iarcuschin.simpleratingbar.SimpleRatingBar
    android:id="@+id/ratingBar3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    app:srb_rating="3.6"
    app:srb_starBackgroundColor="@color/white"
    app:srb_fillColor="@color/material_greenA700"
    app:srb_borderColor="@color/material_white"
    app:srb_pressedFillColor="@color/material_greenA700"
    app:srb_starSize="30dp"
    app:srb_drawBorderEnabled="false"
    />

Надеюсь, это полезно.