您的位置:首页 > 移动开发 > Android开发

Android通过反射获取资源ID

2015-12-28 18:47 555 查看
通过反射获取布局文件:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

int id = this.getResources().getIdentifier("layout_test", "layout", this.getPackageName());

LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(id, null);

setContentView(view);
}


使用getResources().getIdentifier(),传入三个参数:布局文件名,资源类型,包名;返回值为资源的ID。

使用:包名+“:”+“layout/layout_name”获取layout控件:

int id =getResources().getIdentifier(getPackageName()+":layout/layout_test",null,null);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(id, null);
setContentView(view);


使用ID获取控件:

int imageViewId = getResources().getIdentifier("id_layout_test_image", "id", getPackageName());
ImageView imageView = (ImageView) findViewById(imageViewId);


使用图片名获取图片:

int drawableId = getResources().getIdentifier("bjmgf_sdk_cup", "drawable", getPackageName());
Drawable res = getResources().getDrawable(drawableId);


或者使用URI获取图片:

String uri = "@drawable/bjmgf_sdk_cup";
int imageResource = getResources().getIdentifier(uri, null, getPackageName());
Drawable res = getResources().getDrawable(imageResource);


在开发属于自己的控件,用到了attr自定义属性,在期间发现一个问题,即styleable的数值无法使用context.getResources().getIdentifier来获取,结果永远都是0,而且styleable中还包括数组数据,所以最后还是用java的反射方法来获取

xml文件中的定义格式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TestMySelfTextView">
<attr name="myTextColor" format="color"></attr>
<attr name="myTextSize" format="dimension" />
<attr name="myString" format="string" />

</declare-styleable>
</resources>


R文件中的styleable子类中的属性字段格式:

public static final class styleable {
public static final int[] TestMySelfTextView= {
0x7f01000a, 0x7f01000b,0x7f01000c
};
public static final int TestMySelfTextView_myTextColor = 0;
public static final int TestMySelfTextView_myTextSize = 1;
public static final int TestMySelfTextView_myString = 2;
}


读取方式:遍历R类得到styleable数组资源下的子资源,1.先找到R类下的styleable子类,2.遍历styleable类获得字段值

根据名字获取int数组:

public static int[] getStyleableIntArray(Context context, String name) {
try {
Field[] fields = Class.forName(context.getPackageName() + ".R$styleable").getFields();//.与$ difference,$表示R的子类
for (Field field : fields) {
if (field.getName().equals(name)) {
int ret[] = (int[]) field.get(null);
return ret;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}


利用int数组,获得TypeArray:调用Context#obtainStyledAttributes(),参数attrs是自定义view的构造器传入参数

int[] a = ResourceId.getStyleableIntArray(context, "TestMySelfTextView");
TypedArray typedArray = context.obtainStyledAttributes(attrs, a);


通过TypeArray#getString()获取配置资源:

typedArray.getString(ResourceId.getStyleableFieldId(context, "TestMySelfTextView", "myString"))


这里获取资源ID的方式和获取styleable int数组不同,这里直接返回int值:

/**
* 遍历R类得到styleable数组资源下的子资源,1.先找到R类下的styleable子类,2.遍历styleable类获得字段值
*
* @param context
* @param styleableName
* @param styleableFieldName
* @return
*/
public static int getStyleableFieldId(Context context, String styleableName, String styleableFieldName) {
String className = context.getPackageName() + ".R";
String type = "styleable";
String name = styleableName + "_" + styleableFieldName;
try {
Class<?> cla = Class.forName(className);
for (Class<?> childClass : cla.getClasses()) {
String simpleName = childClass.getSimpleName();
if (simpleName.equals(type)) {
for (Field field : childClass.getFields()) {
String fieldName = field.getName();
if (fieldName.equals(name)) {
return (int) field.get(null);
}
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: