Retrieving all Drawable resources from Resources object

30,848

Solution 1

If you find yourself wanting to do this you're probably misusing the resource system. Take a look at assets and AssetManager if you want to iterate over files included in your .apk.

Solution 2

Okay, this feels a bit hack-ish, but this is what I came up with via Reflection. (Note that resources is an instance of class android.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 */
}

If anyone has a better solution that makes better use of Android calls I might not be aware of, I'd definitely like to see them!

Solution 3

i used getResources().getIdentifier to scan through sequentially named images in my resource folders. to be on a safe side, I decided to cache image ids when activity is created first time:

    private void getImagesIdentifiers() {

    int resID=0;        
    int imgnum=1;
    images = new ArrayList<Integer>();

    do {            
        resID=getResources().getIdentifier("img_"+imgnum, "drawable", "InsertappPackageNameHere");
        if (resID!=0)
            images.add(resID);
        imgnum++;
    }
    while (resID!=0);

    imageMaxNumber=images.size();
}

Solution 4

I have taken Matt Huggins great answer and refactored it to make it more generic:

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 */
    }   
}

Usage:

loadDrawables(R.drawable.class);

Solution 5

You should use the Raw folder and AssetManager, but if you want to use drawables because why not, here is how...

Let's suppose we have a very long file list of JPG drawables and we want to get all the resource ids without the pain of retrieving one by one (R.drawable.pic1, R.drawable.pic2, ... etc)

//first we create an array list to hold all the resources ids
ArrayList<Integer> imageListId = new ArrayList<Integer>();

//we iterate through all the items in the drawable folder
Field[] drawables = R.drawable.class.getFields();
for (Field f : drawables) {
    //if the drawable name contains "pic" in the filename...
    if (f.getName().contains("image"))
        imageListId.add(getResources().getIdentifier(f.getName(), "drawable", getPackageName()));
}

//now the ArrayList "imageListId" holds all ours image resource ids
for (int imgResourceId : imageListId) {
     //do whatever you want here
}
Share:
30,848

Related videos on Youtube

Matt Huggins
Author by

Matt Huggins

Currently developing with Ruby (Rails) and Javascript (React/Redux). Variety of past &amp; present experience includes mobile development (React Native, Android, Cordova), SQL, Java, PHP, C/C++, etc.

Updated on June 06, 2020

Comments

  • Matt Huggins
    Matt Huggins about 4 years

    In my Android project, I want to loop through the entire collection of Drawable resources. Normally, you can only retrieve a specific resource via its ID using something like:

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

    However, I want to get all Drawable resources where I won't know their ID's beforehand. Is there a collection I can loop through or perhaps a way to get the list of resource ID's given the resources in my project?

    Or, is there a way for me in Java to extract all property values from the R.drawable static class?

  • Matt Huggins
    Matt Huggins almost 14 years
    This works, but the problem with it is that every time I add a drawable to the folder, I also have to update this string array. I'm looking for something more automatic.
  • Matt Huggins
    Matt Huggins almost 14 years
    Thanks, I'll check that out. I'm attempting to load textures into memory for use in an OpenGL game.
  • Matt Huggins
    Matt Huggins almost 14 years
    This works and is less project-specific (due to class R being project-specific), which I like. The only difference was that I has to use the "assets" folder instead of the "res" folder.
  • Steve Blackwell
    Steve Blackwell over 13 years
    This is the only way to get resources (as opposed to assets) that I can find. Note that you don't need drawableResources. Since all the fields of R are static, getInt() can take null.
  • Matt Huggins
    Matt Huggins over 10 years
    I like the creativity behind this hack. ;)
  • Al Lelopath
    Al Lelopath over 10 years
    Just a detail to note: java.lang.reflect.Field
  • Adilli Adil
    Adilli Adil over 8 years
    And how do you get the resource from the field object?
  • Alecs
    Alecs over 8 years
    You can write a code like this: imageView.setImageDrawable(Utils.getDrawable(declaredFields.‌​get(position).getNam‌​e(), context))
  • Pj Rigor
    Pj Rigor over 7 years
    At what point would this be called? I created a function that returns an image array but I am getting an error saying that the array is null therefore it has no length @SteveBlackwell
  • Steve Blackwell
    Steve Blackwell over 7 years
    @PjRigor It's hard to know why you're getting that result without seeing some code. It's probably best to post a new question.
  • Sojan P R
    Sojan P R over 7 years
    What a creativity! Thank you so much
  • Paul Burke
    Paul Burke over 5 years
    This is not an answer.