资源是颜色还是可绘制对象?

3

我创建了一个扩展ImageView的小型自定义视图。

我的自定义视图提供了一个方法showError(int),可以传递资源id,该资源id应显示为图像视图的内容。如果我能够传递简单的颜色资源id或可绘制资源id,那就太好了。

问题是:如何确定传递的资源id是Drawable还是Color?

我的当前方法类似于:

class MyImageView extends ImageView{

     public void showError(int resId){

        try{
            int color = getResources().getColor(resId);
            setImageDrawable(new ColorDrawable(color));
        }catch(NotFoundException e){
            // it was not a Color resource so it must be a drawable
            setImageDrawable(getResources().getDrawable(resId));
        }

     }
}

这样做安全吗?我的假设是,资源ID确实是唯一的。我的意思不是在R.drawable或R.color中唯一,而是在R中完全唯一。

因此,没有

R.drawable.foo_drawable = 1;
R.color.foo_color = 1;

这是正确的吗,即id 1 只会被分配给这两个资源中的一个而不是两个都有?

4个回答

8
您可能想从资源中查找一个TypedValue,以便确定该值是Color还是Drawable。像这样的内容应该可以正常工作,而无需抛出和捕获异常:
TypedValue value = new TypedValue();
getResources().getValue(resId, value, true); // will throw if resId doesn't exist

// Check whether the returned value is a color or a reference
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
    // It's a color
    setImageDrawable(new ColorDrawable(value.data));
} else if (value.type == TypedValue.TYPE_REFERENCE) {
    // It's a reference, hopefully to a drawable
    setImageDrawable(getResources().getDrawable(resId));
}

那正是我正在寻找的!谢谢。 - sockeqwe
使用getDrawable并检查它是哪个实例(例如ColorDrawable或BitmapDrawable)也不可能吗? - Gerard

1
首先,getResources 获取的所有内容都是 drawable。ColorDrawable 只是 Drawable 的一个子类,BitMapDrawable 和许多其他类也是如此(http://developer.android.com/guide/topics/resources/drawable-resource.html)。
此外,Android 确保 R 文件中的所有值都是唯一的(因此即使它们是不同实例的,也不可能获得与您描述的相同的值)。唯一返回相同值的情况是资源未被找到(将返回0)。在这里找到关于唯一 ID 的部分 here
希望这可以帮助您。

你的第一点是不正确的。ColorBitmap不是Drawable的子类,尽管ColorDrawableBitmapDrawable是。 - Alex MDC
是的,这就是关键点...所以我必须区分 setImageDrawable(new ColorDrawable(color))setImageDrawable(getResources().getDrawable(resId)); 对吧?那么我上面的解决方案似乎是正确的? - sockeqwe
啊,是的,你说得对,但我的第二个真正的观点仍然成立。Android保证R中生成的所有ID都是唯一的。 - Gerard
我认为如果try失败了,你的最终子句就不会起作用。我认为它也无法找到资源。 - Gerard

0

你也可以这样做

 TypedValue value = new TypedValue();

 context.getResources().getValue(resId, value, true);

// Check if it is a reference
if (value.type == TypedValue.TYPE_REFERENCE) {
    ....
 }

0

打开你的 R.java 文件,你会看到所有资源 ID 都在里面定义了,每个 ID 都有一个唯一的 32 位数字。它们也按类型分组在一起。例如,你应该能看到所有 drawable 的 ID 分组在一起:

public static final class drawable {
    public static final int my_drawable_1=0x7f020000;
    public static final int my_drawable_2=0x7f020001;

资源ID的格式为PPTTNNNN,其中PP始终为0x7f,TT是类型。我预计您所有的可绘制对象都使用“02”作为类型,但最好检查一下您自己的文件。在这种情况下,如果ID在0x7f020000和0x7f029999之间,则可以假定它是一个可绘制对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接