通過反射獲取布局文件:
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; }