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?

Balázs Édes
  • 13,452
  • 6
  • 54
  • 89

4 Answers4

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);  
}
Rahmathullah M
  • 2,676
  • 2
  • 27
  • 44
  • This is the correct solution. Using reflection is by far the worst way of doing this. – Falmarri Aug 05 '12 at 07:11
  • 2
    @Falmarri Care to explain why? – nullpotent Aug 05 '12 at 07:29
  • 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? :( – Balázs Édes Aug 05 '12 at 09:08
  • 1
    @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` – Falmarri Aug 07 '12 at 17:21
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.

Vaandu
  • 4,857
  • 12
  • 49
  • 75
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.

nullpotent
  • 9,162
  • 1
  • 31
  • 42
  • @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](http://stackoverflow.com/questions/5492236/why-does-reflection-slow-down-android-phone) and the [linked one in it](http://stackoverflow.com/questions/435553/java-reflection-performance). Though I'd say measure and make your own decisions. It just *sounds* like a bad idea from my experience. –  Aug 05 '12 at 07:53
  • 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. – Balázs Édes Aug 05 '12 at 09:13
  • 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. – nullpotent Aug 05 '12 at 10:04
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!

Balázs Édes
  • 13,452
  • 6
  • 54
  • 89
  • Well, okay; but I hope you're aware of all the pros and cons of using reflection API on Dalvik. – nullpotent Aug 05 '12 at 10:42
  • 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? – Balázs Édes Aug 06 '12 at 17:45