Пользовательские стили RatingBar показывают только одну точку, другое странное поведение

У меня есть следующий код, настроенный для создания пользовательского стиля RatingBar на Android:

In res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyRatingBar" parent="@android:style/Widget.RatingBar">
        <item name="android:minHeight">@dimen/rating_bar_height</item>
        <item name="android:maxHeight">@dimen/rating_bar_height</item>
        <item name="android:progressDrawable">@drawable/circle_ratingbar_full</item>
    </style>
</resources>

In res/drawable/circle_ratingbar_full.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/circle_ratingbar_full_empty" />
    <item
        android:id="@android:id/secondaryProgress"
        android:drawable="@drawable/circle_ratingbar_full_empty" />
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/circle_ratingbar_full_filled" />
</layer-list>

In res/drawable/circle_ratingbar_full_empty.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true"
          android:state_window_focused="true"
          android:drawable="@drawable/button_disabled" />

    <item android:state_focused="true"
          android:state_window_focused="true"
          android:drawable="@drawable/button_disabled" />

    <item android:state_selected="true"
          android:state_window_focused="true"
          android:drawable="@drawable/button_enabled" />

    <item android:drawable="@drawable/button_disabled" />

</selector>

In res/drawable/circle_ratingbar_full_filled.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true"
          android:state_window_focused="true"
          android:drawable="@drawable/button_enabled" />

    <item android:state_focused="true"
          android:state_window_focused="true"
          android:drawable="@drawable/button_enabled" />

    <item android:state_selected="true"
          android:state_window_focused="true"
          android:drawable="@drawable/button_enabled" />

    <item android:drawable="@drawable/button_enabled" />

</selector>

Кроме того, у меня есть два изображения, res/drawable/button_enabled.png и res/drawable/button_disabled.png, которые я хочу использовать для замены звездочек на RatingBar.

У Android Studio, похоже, нет проблем с отдельными чертежами. Однако, когда я использую этот стиль в RatingBar в макете xml, RatingBar, который в своем стиле по умолчанию работает без проблем, имеет несколько проблем:

  1. Вместо переменного количества рисунков рейтинга я вижу только один, вне зависимости от количества выставленных звезд.
  2. Если я не установлю minHeight и maxHeight в стиле, RatingBar растянется на большую высоту, но все равно будет только одна пользовательская звезда (круг).
  3. Если его поместить внутрь представления элемента ListView, само представление элемента больше не будет кликабельным (представление элемента кликабельно со стилями по умолчанию).

Есть ли что-то, чего мне не хватает в этой настройке? Я прибегнул к копированию рисунков прямо из стилей RatingBar по умолчанию в SDK и замене своих значений (что приводит к приведенному выше коду), и это все еще не работает.

Фрагмент использования в макете:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/accessory_view">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/rating_min_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Min Value"
            android:paddingLeft="5dp"/>

        <TextView
            android:id="@+id/rating_max_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Max Value"
            android:paddingLeft="5dp"/>
    </LinearLayout>

    <RatingBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:id="@+id/rating"
        style="@style/MyRatingBar"
        android:stepSize="1.0"/>

</LinearLayout>

ОБНОВЛЕНИЕ

После дальнейшего тестирования я обнаружил, что щелчок по любой части одиночной точки, которую я вижу, фактически изменит рейтинг на значение, соответствующее где я щелкнул по нему. Таким образом, кажется, что RatingBar действует как ProgressBar с шагом 0,5. Таким образом, вместо того, чтобы использовать один раз для каждой звезды, он, кажется, использует рисуемый once в качестве фона всей области RatingBar.

Кто-нибудь знает, как сделать так, чтобы я мог просто заменить звездочки и сохранить все остальное поведение RatingBar?


person Josh Kovach    schedule 02.12.2014    source источник
comment
Я попытался сделать именно то, что вы делаете, и в моем предварительном просмотре макета все выглядит нормально. Можете ли вы показать, как вы используете его в макете?   -  person JstnPwll    schedule 02.12.2014
comment
Обновлено, чтобы показать использование   -  person Josh Kovach    schedule 02.12.2014
comment
Я сделал тестовый XML-макет, соответствующий вашему фрагменту, все еще выглядит нормально. Просто чтобы уточнить, он неправильно отображается в предварительном просмотре вашего макета И при тестировании, верно?   -  person JstnPwll    schedule 02.12.2014
comment
Это правильно. Кроме того, я использую последнюю версию SDK и Android Studio 1.0.RC2.   -  person Josh Kovach    schedule 02.12.2014
comment
Хм, это странно. :\ Я не могу воспроизвести это в своей среде.   -  person JstnPwll    schedule 02.12.2014
comment
Это хоть что-то, чтобы продолжать. Спасибо за проверку.   -  person Josh Kovach    schedule 02.12.2014
comment
Я попробовал это в новом проекте, и он все еще делает то же самое, и попробовал это на компьютере коллеги с теми же результатами.   -  person Josh Kovach    schedule 04.12.2014
comment
Интересный. Я был бы готов опробовать ваш код на своей машине, если вы отчаянно нуждаетесь в решении, возможно, я смогу найти проблему.   -  person JstnPwll    schedule 05.12.2014
comment
Пример приложения находится здесь: github.com/shekibobo/custom-rating-bar-test   -  person Josh Kovach    schedule 05.12.2014


Ответы (2)


Я открыл ваш тестовый проект и провел отладку методом проб и ошибок. Мой вывод заключается в том, что вы не можете использовать чертежи формы XML в качестве progressDrawables в файле RatingBar. RatingBar drawables платформы Android - это все .png файлы, что является довольно хорошим показателем того, что XML drawables, вероятно, не поддерживаются. Я пытался использовать растровые рисунки в вашем тестовом проекте, и они работали нормально.

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

person JstnPwll    schedule 04.12.2014
comment
Спасибо за вашу помощь. Оказалось, что .png, которые я использовал, на самом деле были .9.png, что дало бы понять, почему это не сработало. По-видимому, все, что можно растянуть, нельзя использовать в качестве замены для рисования. - person Josh Kovach; 05.12.2014
comment
Отлично, рад, что смог направить вас в правильном направлении. В качестве бонуса я узнал кое-что новое. - person JstnPwll; 05.12.2014

Эту проблему легко решить. Вы должны перейти в свой Gradle (модуль: приложение) и изменить совместимость. Замените на этот:

'com.android.support:appcompat-v7:22.1.1'

А затем замените расширение ActionBarActivity вашей MainActivity, потому что этот класс устарел. Теперь вы должны использовать AppCompatActivity.

Подробнее читайте здесь: https://plus.google.com/+AndroidDevelopers/posts/LNyDnnBYJ8r

person Diogo Borges    schedule 28.05.2015