8

I'm working on an Android project, and i have a lot of drawables. These drawables are all named like icon_0.png, icon_1.png ... icon_100.png. I want to add all the resource id's of these drawables to an ArrayList of Integers. (For those, who do not know android, only Java, i am talking about static variables, in a static inner class of a class, like R.drawable.icon_0. All of this static variables are Integers.)

Is there a more efficient way to do this, than adding them one by one? Like

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(R.drawable.icon_1);
list.add(R.drawable.icon_2);
...
list.add(R.drawable.icon_100);

Can i loop through them somehow? Like

for(int i=0; i<100; i++)
{
    list.add(R.drawable.icon_+i);  //<--- I know this doesn't work.
}

I have no control over the file where these static integers are, and i cannot create the drawables in runtime.

Any help would be appreciated!

EDIT

Okay, i read the answers, but i have one major problem: I don't have access to any Context instances where i need to create this array/list of ids (i do it in a static initialzer block), so the getResources() method, what two of the answers suggested wont work. Is there any other way of doing this?

1

4 Answers 4

4

Create an XML file in the values folder in your resource directory.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="myIcons">
    <item>@drawable/icon1</item>
    <item>@drawable/icon2</item>
    <item>@drawable/icon3</item>
    <item>@drawable/icon4</item>
    <item>@drawable/icon5</item>
    ...
    ...
</array>
</resources>

Go through the following code, you will get the idea.

Resources res = getResources();
TypedArray myIcons= res.obtainTypedArray(R.array.myIcons);  //mentioned  in the XML
for(int i=0; i<100; i++)
{
    Drawable drawable = myIcons.getDrawable(i);
    list.add(drawable);  
}
Sign up to request clarification or add additional context in comments.

4 Comments

This is the correct solution. Using reflection is by far the worst way of doing this.
@Falmarri Care to explain why?
Hi! thanks for the answer, i really like it. My only problem is (i didn't mention it in the question), that the list i need to create is a static field, and i can only upload it in a static initializer block, where i have no access to any Context instances. Any ideas in this case? :(
@iccthedral: Because reflection is very very expensive and not type safe. Android already has a method of doing exactly what OP wants. OP, you're going to need a context. Period. Your example only adds integers to a list, it doesn't actually load any drawables. If you REALLY need them as early as possible, you should load them in your application's overall application's onCreate method. That is, your class that extends Application
3

You can try this. YourClassName.class.getFields();

Field[] fields = R.drawable.class.getFields();

you can iterate all fields, and you may need to filter it if u have additional fields than you need.

Comments

0

One way would be to use reflection API.

Something along the lines...

Field[] fields =  R.drawable.class.getFields();
List<String> names = new ArrayList<String>(); 
for (Field field : fields) {
    if(field.getName().startsWith("icon")) 
       names.add(field.getName());    
}

int resid = getResources().getIdentifier(names.get(0), "drawable", "com.org.bla");

I haven't tested this, but you get the idea.

3 Comments

@AljoshaBre Because reflection is really slow (esp. on Dalvik). You can get away with getting one resid or two. In this case we are talking about 100. If I remember correctly, getIdentifier() uses reflection internally too, which doesn't make things any better. Have a look at this question and the linked one in it. Though I'd say measure and make your own decisions. It just sounds like a bad idea from my experience.
Thanks! is there any way, to do this without the getResources() function? I don't have access to any Contexts at the point, where i need to create this list.
Oh boy, it is painfully slow on Dalvik. My bad, but hey - if you cache the results and use getIdentifier(...) appropriately, this solution should be fine. However, I would go with XML anyway; as Rahmathullah showed.
0

Here is what i ended up doing:

icons = new ArrayList<Integer>(100);

//get all the fields of the R.drawable class.       
Field  [] fields = R.drawable.class.getDeclaredFields();

//create a temporary list for the names of the needed variables.
ArrayList <String> names = new ArrayList<String>(100);

//select only the desired names.
for(int i=0; i<fields.length; i++)
    if(fields[i].getName().contains("icon_"))
        names.add(fields[i].getName());

//sort these names, because later i want to access them like icons.get(0)
//what means i want icon_0.
Collections.sort(names);

try
{
    for(int i=0; i<names.size(); i++)
    {
        //get the actual value of these fields, 
        //and adding them to the icons list.
        int id = R.drawable.class.getField(names.get(i)).getInt(null);
        icons.add(id);
    }
}
catch(Exception ex)
{
    System.out.println(ex.getMessage());
}

I'm sure, that it's not the fastest way but it's working. I will accept AljoshaBre's solution, because his answer led me to this solution.

Thanks everybody for the help!

2 Comments

Well, okay; but I hope you're aware of all the pros and cons of using reflection API on Dalvik.
It's the second or third time, i see the reflection API in action, so i have no clue about the benefits/disadvantages, and i don't even know what Dalvik means. I just didn't want to use the xml method, because i had to type just as much, as manually adding the ids to the list. So could you please provide some sources about the Reflection stuff?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.