通常情况下我们找一个资源的id一般都是这样做的
通过R.layout.activity_main找到布局文件的id;通过R.id.tv_text找到名为tv_text的id
有时我们并不想通过R文件来找到资源的id,而是希望通过资源名字来找到资源的id,其中一种应用场景是在插件中,一个插件中包含资源文件的话,R类所属的包是不断的变化的,如果通过R来找资源文件的话,必须在安装好插件之后手动去修改导入R的包名,确保资源文件能够正确的被找到,这样做的话非常的麻烦。如果能避免使用到R文件就不需要修改了,下面给出两种方法,一种是利用android提供的api通过资源名称来找资源id。一种是通过反射的方式获取资源id.
第一种方式,通过getIdentifier获取资源id
1.1 通过资源名称找到布局文件的id,例如布局文件activity_main.xml
private int getResId(String resourceName){
Resources resources = getResources();
int resId = resources.getIdentifier(resourceName,"",getPackageName());
// int resId = resources.getIdentifier(getPackageName() + ":layout/" + resourceName, null, null);此方法也可以用
return resId;
}
1.2通过id的名字找到id,例如在TextView中定义的tv_text
private int getId(String idName){
Resources resources = getResources();
int resId = resources.getIdentifier(idName, "id", getPackageName());
return resId;
}
1.3 通过图片名字获取id
private int getDrawableId(String drawableName){
Resources resources = getResources();
int resId =resources .getIdentifier(drawableName,"drawable", getPackageName())
return resId;
}
1.4通过字符串名字获取id
private int getStringId(String stringName){
Resources resources = getResources();
int resId =resources.getIdentifier(stringName,"string", getPackageName());
return resId;
}
下面是getIdentifier 的接口文档:
public int getIdentifier (String name, String defType, String defPackage)
一、传参方式1 resources.getIdentifier(getPackageName() + ":layout/" + resourceName, null, null);
重要的是第一个参数,格式是:包名 + : + 资源文件夹名 + / +资源名,其他的都可以为null
二、传参方式2 resources. getIdentifier(“”tv_text“”, "id", getPackageName());
第一个参数为id名,第二个为资源属性是id或者是Drawable,第三个为包名。
如果找到了,返回资源Id,如果找不到,返回0
第二种方式,通过反射的方式获取资源id
第一种方式能够满足绝大多数的需求,但是当需要获取的资源返回值是一个数组时就不能使用第一种方式了,因为getIdentifier的返回值是一个int类型的值,这时就需要通过反射来获取了。
2.1 获取values下的attr.xml中attrs.xml中的CalendarPickerView
<?xml version='1.0' encoding='utf-8'?>
<resources>
<declare-styleable name="CalendarPickerView">
<attr name="android:background" />
<attr format="color" name="tsquare_dividerColor" />
<attr format="reference" name="tsquare_dayBackground" />
<attr format="color" name="tsquare_dayTextColor" />
<attr format="color" name="tsquare_titleTextColor" />
<attr format="boolean" name="tsquare_displayHeader" />
<attr format="color" name="tsquare_headerTextColor" />
</declare-styleable>
</resources>
private int[] getStyleableArryId(String styleableName){
try {
Class<?> loadClass = mContext.getClassLoader().loadClass(mContext.getPackageName() + ".R");
Class<?>[] classes = loadClass.getClasses();
for(int i=0 ;i<classes.length ;i++){
Class<?> resClass = classes[i];
// Log.e("399", resClass.getName());
if(resClass.getName().equals(mContext.getPackageName() + ".R$styleable")){
// resClass.getDeclaredField("DayPickerView");
Field[] fields = resClass.getFields();
for (int j = 0; j < fields.length; j++) {
// Log.e("399", fields[j].getName());
if(fields[j].getName().equals(styleableName)){
int[] styleable = (int[]) fields[j].get(null);
//Log.e("399", styleable+"");
return styleable;
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
2.2 获取styleable的资源id
private int getStyleableId(String styleableName) {
try {
Class<?> loadClass = mContext.getClassLoader().loadClass(mContext.getPackageName() + ".R");
Class<?>[] classes = loadClass.getClasses();
for (int i = 0; i < classes.length; i++) {
if (classes[i].getName().equals(mContext.getPackageName() + ".R$styleable")) {
Field field = classes[i].getField(styleableName);
int attrId = field.getInt(null);
return attrId;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}
2.3 获取attr的资源id
public int getAttrId(String attrName) {
try {
Class<?> loadClass = mContext.getClassLoader().loadClass(mContext.getPackageName() + ".R");
Class<?>[] classes = loadClass.getClasses();
for (int i = 0; i < classes.length; i++) {
if (classes[i].getName().equals(mContext.getPackageName() + ".R$attr")) {
Field field = classes[i].getField(attrName);
int attrId = field.getInt(null);
return attrId;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}