为什么我不能施展?

时间:2015-04-19 01:10:00

标签: java android ratingbar

我需要更改星星ratingBar的颜色,但会有例外,为什么会发生这种情况并且完全被接受?

ResultActivity

private void setDados() {
        TextView text = (TextView) findViewById(R.id.textView3);
        text.setText((text.getText()) + "" + corretas);
        RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
        ratingBar.setRating((100*corretas)/(corretas+erradas));
        LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
        try {
            stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

日志

04-18 22:02:39.828  31732-31732/com.morais.daniela.doctorquiz E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.morais.daniela.doctorquiz/com.morais.daniela.doctorquiz.Activity.ResultActivity}: java.lang.ClassCastException: android.support.v7.internal.widget.TintDrawableWrapper cannot be cast to android.graphics.drawable.LayerDrawable
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
            at android.app.ActivityThread.access$600(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4448)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.ClassCastException: android.support.v7.internal.widget.TintDrawableWrapper cannot be cast to android.graphics.drawable.LayerDrawable
            at com.morais.daniela.doctorquiz.Activity.ResultActivity.setDados(ResultActivity.java:44)
            at com.morais.daniela.doctorquiz.Activity.ResultActivity.onCreate(ResultActivity.java:36)
            at android.app.Activity.performCreate(Activity.java:4465)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
            at android.app.ActivityThread.access$600(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4448)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
            at dalvik.system.NativeStart.main(Native Method)

更新 :这在API 5.0及更高版本中不起作用,我如何处理Ice Cream及更高版本的作品?无需创建星形图像

4 个答案:

答案 0 :(得分:1)

因为在Android 5中引入了着色drawable,所以appcompat-v7库在TintDrawable类中包装了drawable。你可以用反射绕过它。使用this gist然后使用此代码段:

LayerDrawable stars = (LayerDrawable) XpeceDrawableWrapper.getDrawable(ratingBar.getProgressDrawable());

请务必致电ratingBar.setProgressDrawable(stars)以更换原来着色的可画画。

编辑:这个要点可能与proguard不兼容(一些保持类规则应该修复它)。

答案 1 :(得分:0)

getPorgressDrawable会返回Drawable个对象。 LayerDrawable扩展了Drawable。

您明确地将Drawable对象强制转换为LayerDrawable,结果是运行时错误,因为Drawable对象不是 a LayerDrawable 。只有LayerDrawable个对象为Drawable

您可能需要查看this关于Java中的类型转换。

答案 2 :(得分:0)

最简洁的方法是定义您自己的Drawable,例如:Android RatingBar change star colors

转换错误是因为android支持库。支持库将大多数android小部件drawables包装到扩展TintDrawableWrapperDrawableWrapper中。您只能通过使用反射访问字段

来访问真实(包装)可绘制
private final Drawable mDrawable;

应该是您要找的LayerDrawable

但请注意,可以随时使用任何支持库更新来更改字段的名称。

另一个" hacky"方法是使用着色方法

public void setTint(int tint);
public void setTintList(ColorStateList tint)

DrawableWrapper中定义。由于DrawableWrapper具有包可见性,因此您必须编写一个小帮助类并将其放入android.support.v7.internal.widget包中以访问这些方法

答案 3 :(得分:0)

今天在以编程方式创建RatingBar时遇到了类似的问题。以下解决方法也适用于使用AppCompatRatingBar的 Android 4.x 设备:

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