2012-04-29 3 views
6

Итак, у меня есть код, который генерирует идентификаторы для ряда элементов, используя AtomicInteger, который установлен по умолчанию в Integer.MAX_VALUE и уменьшается оттуда с каждым который получает назначенный идентификатор. Таким образом, первое представление с сгенерированным идентификатором будет Integer.MAX_VALUE - 1, второе будет Integer.MAX_VALUE - 2 и т. Д. Проблема, которую я боюсь, - это столкновение с идентификаторами, сгенерированными Android в R.java.Проверка наличия идентификатора в ресурсах (R.id.something)

Итак, мой вопрос заключается в том, как определить, используется ли идентификатор, и пропустить его, когда я создаю идентификаторы. Я генерирую не более 30 идентификаторов, поэтому это не очень важный приоритет, я хотел бы сделать это как можно скорее ошибкой.

ответ

9

Следующий код покажет вам, если идентификатор является идентификатором или нет.

static final String PACKAGE_ID = "com.your.package.here:id/" 
... 
... 
int id = <your random id here> 
String name = getResources().getResourceName(id); 
if (name == null || !name.startsWith(PACKAGE_ID)) { 
    // id is not an id used by a layout element. 
} 
+0

Спасибо! Это выглядит многообещающе. Я даже не думал об использовании getResources. Я попробую. – Brandon

+0

@Brandon, вы должны обновить свой вопрос, если у вас есть что добавить. Посмотрите на свое редактирование, хотя это будет еще лучше, как ответ на ваш собственный вопрос! – Ben

+4

'name' никогда не будет' null'. вместо этого, 'Resource.NotFoundException' будет вызываться' getResourceName() ', если идентификатор недействителен – sfera

0

Только идея ... вы можете использовать findViewById (int id), чтобы проверить, действительно ли id уже используется.

+2

, который работал бы только в том случае, если контекст был установлен на конкретное представление, в котором находился идентификатор. Другими словами, более одного представления и разных идентификаторов, которые никогда не будут работать как обнаружение. – MikeIsrael

1

Вы можете использовать Java Reflection API для доступа к любым элементам, находящимся в объекте R.id Класс.

Код выглядит так:

Class<R.id> c = R.id.class; 

R.id object = new R.id(); 

Field[] fields = c.getDeclaredFields(); 

// Iterate through whatever fields R.id has 
for (Field field : fields) 
{ 
    field.setAccessible(true); 

    // I am just printing field name and value, you can place your checks here 

    System.out.println("Value of " + field.getName() + " : " + field.get(object)); 
} 
+0

Похоже, это может сработать, но я решил пойти с @Jens ответить – Brandon

3

Я изменил Jens ответ сверху, поскольку, как указано в комментариях, имя никогда не будет равным null, и вместо этого будет выбрано исключение.

private boolean isResourceIdInPackage(String packageName, int resId){ 
    if(packageName == null || resId == 0){ 
     return false; 
    } 

    Resources res = null; 
    if(packageName.equals(getPackageName())){ 
     res = getResources(); 
    }else{ 
     try{ 
      res = getPackageManager().getResourcesForApplication(packageName); 
     }catch(PackageManager.NameNotFoundException e){ 
      Log.w(TAG, packageName + "does not contain " + resId + " ... " + e.getMessage()); 
     } 
    } 

    if(res == null){ 
     return false; 
    } 

    return isResourceIdInResources(res, resId); 
} 

private boolean isResourceIdInResources(Resources res, int resId){ 

    try{    
     getResources().getResourceName(resId); 

     //Didn't catch so id is in res 
     return true; 

    }catch (Resources.NotFoundException e){ 
     return false; 
    } 
} 
Смежные вопросы