为什么我不能演员表?
Why can't I do cast?
我需要更改星星的颜色ratingBar
但是出现异常,为什么会发生并且完全可以接受?
结果活动
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.access0(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.access0(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)
UPDATE:这在 API 5.0 及更高版本中不起作用,我是如何在 Ice Cream 中工作的和更高?无需制作星图
getPorgressDrawable returns a Drawable object. LayerDrawable 扩展了 Drawable。
您正在将 Drawable
对象显式转换为 LayerDrawable
,这导致运行时错误,因为 Drawable
对象 不是 LayerDrawable
。只有一个 LayerDrawable
对象是 Drawable
.
您可能想看看 this 关于 Java 中的类型转换。
因为着色绘图是在 Android 5 中引入的,所以 appcompat-v7 库在 TintDrawable
class 中包装了绘图。您可以使用反射来绕过它。使用 this gist 然后这个片段:
LayerDrawable stars = (LayerDrawable) XpeceDrawableWrapper.getDrawable(ratingBar.getProgressDrawable());
一定要调用 ratingBar.setProgressDrawable(stars)
来替换原来着色的可绘制对象。
编辑:原样的要点可能与混淆器不兼容(一些保持 class 规则应该修复它)。
最简洁的方法是定义您自己的 Drawable
,就像这里建议的那样:Android RatingBar change star colors
转换错误是因为 android 支持库。支持库将大部分 android 小部件可绘制对象包装到 TintDrawableWrapper which extends DrawableWrapper 中。您只能通过使用反射访问字段来访问真实的(包装的)可绘制对象
private final Drawable mDrawable;
这应该是您正在寻找的LayerDrawable
。
但请注意,任何支持库更新都可能随时更改该字段的名称。
另一种"hacky"方法是使用着色方法
public void setTint(int tint);
public void setTintList(ColorStateList tint)
在DrawableWrapper
中定义。由于 DrawableWrapper
具有包可见性,因此您必须编写一个小助手 class 并将其放入 android.support.v7.internal.widget
包中以访问这些方法
今天在以编程方式创建 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);
}
我需要更改星星的颜色ratingBar
但是出现异常,为什么会发生并且完全可以接受?
结果活动
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.access0(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.access0(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)
UPDATE:这在 API 5.0 及更高版本中不起作用,我是如何在 Ice Cream 中工作的和更高?无需制作星图
getPorgressDrawable returns a Drawable object. LayerDrawable 扩展了 Drawable。
您正在将 Drawable
对象显式转换为 LayerDrawable
,这导致运行时错误,因为 Drawable
对象 不是 LayerDrawable
。只有一个 LayerDrawable
对象是 Drawable
.
您可能想看看 this 关于 Java 中的类型转换。
因为着色绘图是在 Android 5 中引入的,所以 appcompat-v7 库在 TintDrawable
class 中包装了绘图。您可以使用反射来绕过它。使用 this gist 然后这个片段:
LayerDrawable stars = (LayerDrawable) XpeceDrawableWrapper.getDrawable(ratingBar.getProgressDrawable());
一定要调用 ratingBar.setProgressDrawable(stars)
来替换原来着色的可绘制对象。
编辑:原样的要点可能与混淆器不兼容(一些保持 class 规则应该修复它)。
最简洁的方法是定义您自己的 Drawable
,就像这里建议的那样:Android RatingBar change star colors
转换错误是因为 android 支持库。支持库将大部分 android 小部件可绘制对象包装到 TintDrawableWrapper which extends DrawableWrapper 中。您只能通过使用反射访问字段来访问真实的(包装的)可绘制对象
private final Drawable mDrawable;
这应该是您正在寻找的LayerDrawable
。
但请注意,任何支持库更新都可能随时更改该字段的名称。
另一种"hacky"方法是使用着色方法
public void setTint(int tint);
public void setTintList(ColorStateList tint)
在DrawableWrapper
中定义。由于 DrawableWrapper
具有包可见性,因此您必须编写一个小助手 class 并将其放入 android.support.v7.internal.widget
包中以访问这些方法
今天在以编程方式创建 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);
}