因此,我有一些代码,它使用默认设置为Integer.MAX_VALUE的AtomicInteger为许多元素生成ID,并从那里为每个被分配了ID的视图递减。因此,生成ID的第一个视图为Integer.MAX_VALUE - 1
,第二个视图为Integer.MAX_VALUE - 2
,等等。我担心的问题是与R.java中Android生成的ID冲突。
所以我的问题是如何检测ID是否已被使用并在生成ID时跳过它。我只生成最多30个ID,所以这不是一个巨大的优先级我想尽可能让它成为无bug。
答案 0 :(得分:9)
以下代码将告诉您标识符是否为id。
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.
}
答案 1 :(得分:4)
我修改了上面的Jens回答,因为正如注释中所述,name永远不会为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;
}
}
答案 2 :(得分: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));
}
答案 3 :(得分:0)
只是一个想法......您可以使用findViewById (int id)
检查id
是否已被使用。
答案 4 :(得分:0)
您可以使用需要最低API 17的View.generateViewId()
。
来自sdk
生成一个适合在setId(int)中使用的值。此值不会与Aapt for R.id在生成时生成的ID值冲突。