Android通過反射獲取資源ID


通過反射獲取布局文件:

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;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM