android - icon - toolbar title



从Resources对象检索所有Drawable资源 (7)

在我的Android项目中,我想遍历整个Drawable资源集合。 通常,您只能使用以下内容通过其ID检索特定资源:

InputStream is = Resources.getSystem().openRawResource(resourceId)

但是,我想获得所有Drawable资源,我不会事先知道他们的ID。 是否有一个我可以循环的集合,或者可能是一种获取资源ID列表的方法,它给出了我项目中的资源?

或者,Java中有没有办法从R.drawable静态类中提取所有属性值?


Answer #1

OP需要drawables,我需要布局。 这就是我想出的布局。 name.startsWith business允许我忽略系统生成的布局,因此您可能需要稍微调整一下。 这应该适用于任何资源类型,方法是修改clz的值。

public static Map<String,Integer> loadLayouts(){
    final Class<?> clz = R.layout.class;
    Map<String,Integer> layouts = new HashMap<>();
    final Field[] fields = clz.getDeclaredFields();
    for (Field field : fields) {
        String name = field.getName();
        if (
                !name.startsWith("abc_")
                && !name.startsWith("design_")
                && !name.startsWith("notification_")
                && !name.startsWith("select_dialog_")
                && !name.startsWith("support_")
        ) {
            try {
                layouts.put(field.getName(), field.getInt(clz));
            } catch (Exception e) {
                continue;
            }
        }
    }
    return layouts;
}

Answer #2

使用这个我的代码

R.drawable drawableResources = new R.drawable();
Class<R.drawable> c = R.drawable.class;
Field[] fields = c.getDeclaredFields();

for (int i = 0, max = fields.length; i < max; i++) {
    final int resourceId;
    try {
        resourceId = fields[i].getInt(drawableResources);
        // call save with param of resourceId
        SaveImage(resourceId);
    } catch (Exception e) {
        continue;
    }
}

...

public void SaveImage(int resId){
    if (!CheckExternalStorage()) {
        return;
    }

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), resID);
    try {
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        OutputStream fOut = null;
        File file = new File(path, "image1.png");
        file.createNewFile();
        fOut = new FileOutputStream(file);
        bmp.compress(Bitmap.CompressFormat.PNG, 100, fOut);
        fOut.flush();
        fOut.close();
        MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
        Log.i(LOGTAG, "Image Written to Exterbal Storage");

    } catch (Exception e) {
        Log.e("saveToExternalStorage()", e.getMessage());
    }
}

Answer #3

好吧,这感觉有点黑客,但这是我通过Reflection提出的。 (注意, resourcesandroid.content.res.Resources类的一个实例。)

final R.drawable drawableResources = new R.drawable();
final Class<R.drawable> c = R.drawable.class;
final Field[] fields = c.getDeclaredFields();

for (int i = 0, max = fields.length; i < max; i++) {
    final int resourceId;
    try {
        resourceId = fields[i].getInt(drawableResources);
    } catch (Exception e) {
        continue;
    }
    /* make use of resourceId for accessing Drawables here */
}

如果有人有一个更好的解决方案,可以更好地利用我可能没有注意到的Android调用,我肯定希望看到它们!


Answer #4

如果您发现自己想要这样做,那么您可能会滥用资源系统。 如果要迭代.apk中包含的文件,请查看assets和AssetManager


Answer #5

我对Matt Huggins给出了很好的答案并重构它以使其更通用:

public static void loadDrawables(Class<?> clz){
    final Field[] fields = clz.getDeclaredFields();
    for (Field field : fields) {
        final int drawableId;
        try {
            drawableId = field.getInt(clz);
        } catch (Exception e) {
            continue;
        }
        /* make use of drawableId for accessing Drawables here */
    }   
}

用法:

loadDrawables(R.drawable.class);

Answer #6

我想反射代码可以工作,但我不明白为什么你需要它。

安装应用程序后,Android中的资源是静态的,因此您可以拥有资源列表或数组。 就像是:

<string-array name="drawables_list">
    <item>drawable1</item>
    <item>drawable2</item>
    <item>drawable3</item>
</string-array>

从您的Activity您可以通过以下方式获得:

getResources().getStringArray(R.array.drawables_list);

Answer #7

这样做:

Field[] declaredFields = (R.drawable.class).getDeclaredFields();




drawable