2014-01-18 3 views
2

Я создал небольшой пользовательский вид, который расширяет ImageView. Мое пользовательское представление предоставляет метод showError(int), где я могу передать идентификатор ресурса, который должен отображаться в виде содержимого изображений. Было бы здорово, если бы я мог передать простой идентификатор ресурса цвета или идентификатор ресурса ресурса.Является ли ресурс цветным или доступным?

Моя проблема: как определить, является ли переданный идентификатор ресурса 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)); 
     } 

    } 
} 

Безопасно ли это сделать? Мое предположение заключается в том, что идентификатор ресурса действительно уникален. Я имею в виду не уникально в R.drawable или R.color, но совершенно уникальный в R

Так что нет

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

Верно ли, что идентификатор 1 будет присвоен только одному из этих ресурсов но не для обоих?

ответ

4

Вы, наверное, хотите посмотреть на 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)); 
} 
+0

Это именно то, что я искал! Спасибо – sockeqwe

+0

Нельзя ли также использовать getDrawable и проверить, какой экземпляр он (например, ColorDrawable или BitmapDrawable?) – Gerard

1

Прежде всего, все, что вы получаете от getResources, - это чертежи. ColorDrawable - это просто подкласс Drawable, как BitMapDrawable и многие другие (http://developer.android.com/guide/topics/resources/drawable-resource.html).

Кроме того, Android гарантирует, что все значения в файле R уникальны (поэтому невозможно получить те же значения, что и вы, даже если они будут иметь разные экземпляры). Единственный случай, когда он возвращал идентичные значения, - это когда ресурс не найден (он вернет 0). Найдите часть об уникальном ID here

Надеется, что это помогает

+0

Ваш первый пункт является неправильным. 'Color' и' Bitmap' не являются подклассами 'Drawable', хотя' ColorDrawable' и 'BitmapDrawable'. –

+0

да, это точка ... Поэтому я должен различать 'setImageDrawable (новый ColorDrawable (цвет))' и 'setImageDrawable (getResources(). GetDrawable (resId));' right? Итак, мое решение сверху кажется правильным? – sockeqwe

+0

Ах да, ты прав, но моя вторая и настоящая точка все еще сохраняется. Android гарантирует, что ВСЕ идентификаторы, сгенерированные в R, уникальны. – Gerard

0

Загляните внутрь своего файла R.java. Вы увидите, что в нем определены все идентификаторы ресурсов, каждый из которых имеет уникальное 32-битное число. Они также группируются по типу. Например, вы должны увидеть все ваши Drawable идентификаторы в группе:

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

Ресурс идентификатор вида PPTTNNNN где PP всегда 0x7F и ТТ типа. Я ожидаю, что все ваши drawables будут использовать '02' для типа, но стоит проверить ваш собственный файл. В этом случае, если идентификатор находится между 0x7f020000 и 0x7f029999, вы можете предположить, что он является доступным.

0

Вы можете сделать в этом случае слишком

TypedValue value = new TypedValue(); 

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

// Check if it is a reference 
if (value.type == TypedValue.TYPE_REFERENCE) { 
    .... 
} 
Смежные вопросы