Android RatingBar: getProgressDrawable не приводится к нужному классу

Я использую

Android RatingBar меняет цвета звезд

Эта строка кода

    LayerDrawable stars = (LayerDrawable) rating_bar.getProgressDrawable();

отлично работает на моем Nexus 4 API эмулятора v21. При попытке того же кода на моем Galaxy S4 API v19, я получаю следующее сообщение об ошибке:

 Caused by: java.lang.ClassCastException: android.support.v7.internal.widget.TintDrawableWrapper cannot be cast to android.graphics.drawable.LayerDrawable

Что происходит?

Я собираю с последними инструментами сборки 22, мой целевой API тоже 22.

5 ответов

Решение

Что происходит, ясно объясняется в сообщении об ошибке:

TintDrawableWrapper cannot be cast to android.graphics.drawable.LayerDrawable

Поддержка lib создает оболочку для поддержки ретро-совместимости, вам просто нужно принять это во внимание. Посмотрите на реализацию lib, она, вероятно, охватывает LayerDrawable,

Вам нужно будет сделать что-то вроде:

LayerDrawable stars = getProgressDrawable(rating_bar);
}

private LayerDrawable getProgressDrawable(RatingBar ratingBar) {
  if (Build.VERSION >= LOLLIPOP) {
    return (LayerDrawable) ratingBar.getProgressDrawable();
  } else {
    // fetch the LayerDrawable based on Google's support implementation,  
    // probably a simple findViewById()
  }
}

LayerDrawable используется в API v21.

Пожалуйста, попробуйте этот трюк, он будет работать нормально, добавив метод getCurrent () для возврата в рисование.

RatingBar ratingBar = (RatingBar) findViewById (R.id.ratingBar);

LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable (). GetCurrent ();

stars.getDrawable (2).setColorFilter (getResources (). getColor (R.color.colorPrimary), PorterDuff.Mode.SRC_ATOP); stars.getDrawable (0).setColorFilter (getResources (). getColor (R.color.white), PorterDuff.Mode.SRC_ATOP); stars.getDrawable (1).setColorFilter (getResources (). getColor (R.color.colorPrimary), PorterDuff.Mode.SRC_ATOP);

Эта проблема возникла сегодня при программном создании RatingBar. Следующий обходной путь работает для меня также на устройствах Android 4.x, использующих AppCompatRatingBar:

AppCompatRatingBar rb = new AppCompatRatingBar(activity);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.CENTER;
rb.setLayoutParams(layoutParams);
rb.setStepSize(1.0f);
rb.setMax(5);

LayerDrawable layerDrawable = null;
if (rb.getProgressDrawable() instanceof LayerDrawable) {
    layerDrawable = (LayerDrawable) rb.getProgressDrawable();
} else if (rb.getProgressDrawable() instanceof DrawableWrapper) {
    DrawableWrapper wrapper = (DrawableWrapper) rb.getProgressDrawable();
    if (wrapper.getWrappedDrawable() instanceof LayerDrawable) {
        layerDrawable = (LayerDrawable) wrapper.getWrappedDrawable();
    }
}

if (layerDrawable != null) {
    layerDrawable.getDrawable(2).setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
    layerDrawable.getDrawable(0).setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
    layerDrawable.getDrawable(1).setColorFilter(ContextCompat.getColor(activity, R.color.primary), PorterDuff.Mode.SRC_ATOP);
}

Создание подкласса RatingDialog и использование его вместоandroid.widget.RatingBar работал на меня. Вот код, который я использовал.

Подкласс:

public class RatingBar extends android.widget.RatingBar {
public RatingBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public RatingBar(Context context, AttributeSet attrs) {
    super(context, attrs);
}
}

Тогда в моих раскладках:

 <your.package.RatingBar
    android:id="@+id/rating_bar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    />

Затем в классах, где вы ведете класс, просто используйте your.package.RatingBar вместо android.widget.RatingBar

Другие вопросы по тегам